minint/
datatype.rs

1use std::fmt::Debug;
2
3use rmp::{decode::RmpRead, encode::RmpWrite};
4
5#[derive(Clone, Debug)]
6pub enum Data {
7    Bool(bool),
8    F64(f64),
9    I32(i32),
10    F32(f32),
11    String(String),
12    BoolArray(Vec<bool>),
13    F64Array(Vec<f64>),
14    I32Array(Vec<i32>),
15    F32Array(Vec<f32>),
16    StringArray(Vec<String>),
17}
18impl Data {
19    pub fn from<R: RmpRead>(rd: &mut R, data_type: u8) -> Result<Self, ()> {
20        Ok(match data_type {
21            <bool as DataWrap>::MSGPCK => Self::Bool(<bool as DataWrap>::decode(rd)?),
22            <f64 as DataWrap>::MSGPCK => Self::F64(<f64 as DataWrap>::decode(rd)?),
23            <i32 as DataWrap>::MSGPCK => Self::I32(<i32 as DataWrap>::decode(rd)?),
24            <f32 as DataWrap>::MSGPCK => Self::F32(<f32 as DataWrap>::decode(rd)?),
25            <String as DataWrap>::MSGPCK => Self::String(<String as DataWrap>::decode(rd)?),
26            <Vec<bool> as DataWrap>::MSGPCK => {
27                Self::BoolArray(<Vec<bool> as DataWrap>::decode(rd)?)
28            }
29            <Vec<f64> as DataWrap>::MSGPCK => Self::F64Array(<Vec<f64> as DataWrap>::decode(rd)?),
30            <Vec<i32> as DataWrap>::MSGPCK => Self::I32Array(<Vec<i32> as DataWrap>::decode(rd)?),
31            <Vec<f32> as DataWrap>::MSGPCK => Self::F32Array(<Vec<f32> as DataWrap>::decode(rd)?),
32            <Vec<String> as DataWrap>::MSGPCK => {
33                Self::StringArray(<Vec<String> as DataWrap>::decode(rd)?)
34            }
35            _ => return Err(()),
36        })
37    }
38}
39
40pub trait DataWrap: Sized + Debug {
41    const MSGPCK: u8;
42    const STRING: &'static str;
43
44    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()>;
45    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()>;
46}
47impl<T: DataType + Debug> DataWrap for T {
48    const MSGPCK: u8 = Self::DATATYPE_MSGPCK;
49    const STRING: &'static str = Self::DATATYPE_STRING;
50
51    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
52        Self::decode(rd)
53    }
54    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
55        Self::encode(wr, val)
56    }
57}
58impl<T: DataType + Debug> DataWrap for Vec<T> {
59    const MSGPCK: u8 = T::ARRAYDATATYPE_MSGPCK;
60    const STRING: &'static str = T::ARRAYDATATYPE_STRING;
61
62    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
63        T::decode_array(rd)
64    }
65    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
66        T::encode_array(wr, val)
67    }
68}
69
70pub trait DataType: Sized {
71    const DATATYPE_MSGPCK: u8;
72    const ARRAYDATATYPE_MSGPCK: u8;
73    const DATATYPE_STRING: &'static str;
74    const ARRAYDATATYPE_STRING: &'static str;
75
76    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()>;
77    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()>;
78
79    fn decode_array<R: RmpRead>(rd: &mut R) -> Result<Vec<Self>, ()> {
80        let mut buf = Vec::new();
81
82        let len = rmp::decode::read_array_len(rd).map_err(|_| ())?;
83
84        for _ in 0..len {
85            buf.push(Self::decode(rd)?);
86        }
87
88        Ok(buf)
89    }
90
91    fn encode_array<W: RmpWrite>(wr: &mut W, vals: Vec<Self>) -> Result<(), ()> {
92        rmp::encode::write_array_len(wr, vals.len() as u32).map_err(|_| ())?;
93
94        for val in vals {
95            Self::encode(wr, val)?;
96        }
97
98        Ok(())
99    }
100}
101
102impl DataType for bool {
103    const DATATYPE_MSGPCK: u8 = 0;
104    const ARRAYDATATYPE_MSGPCK: u8 = 16;
105    const DATATYPE_STRING: &'static str = "boolean";
106    const ARRAYDATATYPE_STRING: &'static str = "boolean[]";
107
108    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
109        let ret = rmp::decode::read_bool(rd).map_err(|_| ())?;
110
111        Ok(ret)
112    }
113
114    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
115        rmp::encode::write_bool(wr, val).map_err(|_| ())?;
116
117        Ok(())
118    }
119}
120impl DataType for f64 {
121    const DATATYPE_MSGPCK: u8 = 1;
122    const ARRAYDATATYPE_MSGPCK: u8 = 17;
123    const DATATYPE_STRING: &'static str = "double";
124    const ARRAYDATATYPE_STRING: &'static str = "double[]";
125
126    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
127        let ret = rmp::decode::read_f64(rd).map_err(|_| ())?;
128
129        Ok(ret)
130    }
131
132    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
133        rmp::encode::write_f64(wr, val).map_err(|_| ())?;
134
135        Ok(())
136    }
137}
138impl DataType for i32 {
139    const DATATYPE_MSGPCK: u8 = 2;
140    const ARRAYDATATYPE_MSGPCK: u8 = 18;
141    const DATATYPE_STRING: &'static str = "int";
142    const ARRAYDATATYPE_STRING: &'static str = "int[]";
143
144    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
145        let ret = rmp::decode::read_i32(rd).map_err(|_| ())?;
146
147        Ok(ret)
148    }
149
150    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
151        rmp::encode::write_i32(wr, val).map_err(|_| ())?;
152
153        Ok(())
154    }
155}
156
157impl DataType for f32 {
158    const DATATYPE_MSGPCK: u8 = 3;
159    const ARRAYDATATYPE_MSGPCK: u8 = 19;
160    const DATATYPE_STRING: &'static str = "float";
161    const ARRAYDATATYPE_STRING: &'static str = "float[]";
162
163    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
164        let ret = rmp::decode::read_f32(rd).map_err(|_| ())?;
165
166        Ok(ret)
167    }
168
169    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
170        rmp::encode::write_f32(wr, val).map_err(|_| ())?;
171
172        Ok::<(), _>(())
173    }
174}
175
176impl DataType for String {
177    const DATATYPE_MSGPCK: u8 = 4;
178    const ARRAYDATATYPE_MSGPCK: u8 = 20;
179    const DATATYPE_STRING: &'static str = "string";
180    const ARRAYDATATYPE_STRING: &'static str = "string[]";
181
182    fn decode<R: RmpRead>(rd: &mut R) -> Result<Self, ()> {
183        let mut buf = Vec::new();
184
185        let ret = rmp::decode::read_str(rd, &mut buf).map_err(|_| ())?;
186
187        Ok(ret.to_string())
188    }
189
190    fn encode<W: RmpWrite>(wr: &mut W, val: Self) -> Result<(), ()> {
191        rmp::encode::write_str(wr, &val).map_err(|_| ())?;
192
193        Ok(())
194    }
195}