binn_rs/
value.rs

1use crate::data_type::Type;
2use crate::storage::Storage;
3use crate::subtype::SubType;
4use crate::{data_type, utils, Error, List, Map, Object};
5use byteorder::{BigEndian, ByteOrder};
6
7use crate::error::Result;
8use crate::raw_container::{KeyType, RawContainer};
9use crate::size::Size;
10
11/// Any value in binn format
12#[derive(Debug, PartialEq)]
13pub enum Value<'a> {
14    /// Null
15    Null,
16
17    /// Boolean True
18    True,
19
20    /// Boolean False
21    False,
22
23    /// Unsigned 8bit integer (0..255)
24    UInt8(u8),
25
26    /// Signed 8bit integer (-128..127)
27    Int8(i8),
28
29    /// Unsigned 16bit integer (0..65_535)
30    UInt16(u16),
31
32    /// Signed 16bit integer (-32_768..32_767)
33    Int16(i16),
34
35    /// Unsigned 32bit integer (0..4_294_967_295)
36    UInt32(u32),
37
38    /// Signed 32bit integer (-2_147_483_648..2_147_483_647)
39    Int32(i32),
40
41    /// IEEE 754 single precision floating point number (32bit)
42    Float(f32),
43
44    /// Unsigned 64bit integer (0..18_446_744_073_709_551_615)
45    UInt64(u64),
46
47    /// Signed 64bit integer (-9_223_372_036_854_775_808..9_223_372_036_854_775_807)
48    Int64(i64),
49
50    /// IEEE 754 double precision floating point number (64bit)
51    Double(f64),
52
53    /// UTF-8 encoded string
54    Text(&'a str),
55
56    /// String representing datetime (exact format not specified)
57    DateTime(&'a str),
58
59    /// String representing date (exact format not specified)
60    Date(&'a str),
61
62    /// String representing time (exact format not specified)
63    Time(&'a str),
64
65    /// String representing decimal number (exact format not specified)
66    DecimalStr(&'a str),
67
68    /// Binary data
69    Blob(&'a [u8]),
70
71    /// Container that stores elements sequentially without keys
72    List(List<'a>),
73
74    /// Container that stores key-value pairs with 32bit signed integer as keys
75    Map(Map<'a>),
76
77    /// Container that stores key-value pairs with utf-8 strings as keys
78    /// (with 255 byte limit for their length)
79    Object(Object<'a>),
80
81    /// User-defined type with empty storage
82    Empty(SubType),
83
84    /// User-defined type with Byte storage (8bits)
85    Byte(SubType, u8),
86
87    /// User-defined type with Word storage (16bits)
88    Word(SubType, u16),
89
90    /// User-defined type with DWord storage (32bits)
91    DWord(SubType, u32),
92
93    /// User-defined type with QWord storage (64bits)
94    QWord(SubType, u64),
95
96    /// User-defined type with Text storage (UTF-8 string)
97    UserText(SubType, &'a str),
98
99    /// User-defined type with Blob storage (binary data)
100    UserBlob(SubType, &'a [u8]),
101}
102
103impl<'a> Value<'a> {
104    /// Returns how many bytes \[data\] will take, when it needs \[size\] element
105    ///
106    /// # Panics
107    ///
108    /// Panics if value is container
109    pub(crate) fn data_size(&self) -> Option<usize> {
110        match self {
111            Value::Text(t)
112            | Value::DateTime(t)
113            | Value::Date(t)
114            | Value::Time(t)
115            | Value::DecimalStr(t)
116            | Value::UserText(_, t) => Some(t.len() + 1),
117
118            Value::Blob(b) | Value::UserBlob(_, b) => Some(b.len()),
119
120            Value::List(_) | Value::Map(_) | Value::Object(_) => unreachable!(),
121
122            _ => None,
123        }
124    }
125
126    /// Returns type of this value (subtype, storage)
127    pub(crate) fn get_type(&self) -> Type {
128        match self {
129            Value::Null => data_type::NULL,
130            Value::True => data_type::TRUE,
131            Value::False => data_type::FALSE,
132            Value::UInt8(_) => data_type::UINT8,
133            Value::Int8(_) => data_type::INT8,
134            Value::UInt16(_) => data_type::UINT16,
135            Value::Int16(_) => data_type::INT16,
136            Value::UInt32(_) => data_type::UINT32,
137            Value::Int32(_) => data_type::INT32,
138            Value::Float(_) => data_type::FLOAT,
139            Value::UInt64(_) => data_type::UINT64,
140            Value::Int64(_) => data_type::INT64,
141            Value::Double(_) => data_type::DOUBLE,
142            Value::Text(_) => data_type::TEXT,
143            Value::DateTime(_) => data_type::DATE_TIME,
144            Value::Date(_) => data_type::DATE,
145            Value::Time(_) => data_type::TIME,
146            Value::DecimalStr(_) => data_type::DECIMAL_STR,
147            Value::Blob(_) => data_type::BLOB,
148            Value::List(_) => data_type::LIST,
149            Value::Map(_) => data_type::MAP,
150            Value::Object(_) => data_type::OBJECT,
151            Value::Empty(sub) => Type {
152                storage: Storage::NoBytes,
153                subtype: *sub,
154            },
155            Value::Byte(sub, _) => Type {
156                storage: Storage::Byte,
157                subtype: *sub,
158            },
159            Value::Word(sub, _) => Type {
160                storage: Storage::Word,
161                subtype: *sub,
162            },
163            Value::DWord(sub, _) => Type {
164                storage: Storage::DWord,
165                subtype: *sub,
166            },
167            Value::QWord(sub, _) => Type {
168                storage: Storage::QWord,
169                subtype: *sub,
170            },
171            Value::UserText(sub, _) => Type {
172                storage: Storage::String,
173                subtype: *sub,
174            },
175            Value::UserBlob(sub, _) => Type {
176                storage: Storage::Blob,
177                subtype: *sub,
178            },
179        }
180    }
181
182    /// Returns how many bytes this value will take in buffer
183    pub(crate) fn total_size(&self) -> usize {
184        // size of container is already known
185        match self {
186            Value::List(list) => return list.as_bytes().len(),
187            Value::Map(map) => return map.as_bytes().len(),
188            Value::Object(obj) => return obj.as_bytes().len(),
189            _ => {}
190        }
191
192        let value_type = self.get_type();
193
194        let type_size = value_type.size();
195
196        let fixed_size = value_type.storage.fixed_size();
197        let data_size = self.data_size();
198
199        if let Some(data_size) = fixed_size {
200            type_size + data_size
201        } else if let Some(data_size) = data_size {
202            type_size + Size::new(data_size).unwrap().size() + data_size
203        } else {
204            // value is either fixed size or arbitrary sized
205            unreachable!()
206        }
207    }
208
209    /// Writes this value (\[type\] \[size\] \[data\]) to given buffer
210    /// and returns next insert position, how many bytes were written
211    pub(crate) fn write<'b>(&self, buf: &'b mut [u8]) -> Result<(&'b mut [u8], usize)> {
212        let total_size = self.total_size();
213
214        if buf.len() < total_size {
215            return Err(Error::SmallBuffer(total_size - buf.len()));
216        }
217
218        match self {
219            Value::List(list) => {
220                buf[..total_size].copy_from_slice(list.as_bytes());
221                return Ok((&mut buf[total_size..], total_size));
222            }
223            Value::Map(map) => {
224                buf[..total_size].copy_from_slice(map.as_bytes());
225                return Ok((&mut buf[total_size..], total_size));
226            }
227            Value::Object(obj) => {
228                buf[..total_size].copy_from_slice(obj.as_bytes());
229                return Ok((&mut buf[total_size..], total_size));
230            }
231            _ => {}
232        }
233
234        let value_type = self.get_type();
235
236        let fixed_size = value_type.storage.fixed_size();
237        let data_size = self.data_size();
238
239        // write [type]
240        let mut buf = value_type.write(buf);
241
242        // write [size] if present
243        if let Some(mut data_size) = data_size {
244            if value_type.storage == Storage::String {
245                // for string storage we should not count null terminator in [size] item
246                data_size -= 1;
247            }
248            buf = Size::new(data_size).unwrap().write(buf).unwrap();
249        }
250
251        // write [data] if present
252        match self {
253            Value::Null | Value::True | Value::False | Value::Empty(_) => {}
254
255            Value::UInt8(val) | Value::Byte(_, val) => buf[0] = *val,
256            Value::Int8(val) => buf[0] = *val as u8,
257            Value::UInt16(val) | Value::Word(_, val) => BigEndian::write_u16(buf, *val),
258            Value::Int16(val) => BigEndian::write_i16(buf, *val),
259            Value::UInt32(val) | Value::DWord(_, val) => BigEndian::write_u32(buf, *val),
260            Value::Int32(val) => BigEndian::write_i32(buf, *val),
261            Value::Float(val) => BigEndian::write_f32(buf, *val),
262            Value::UInt64(val) | Value::QWord(_, val) => BigEndian::write_u64(buf, *val),
263            Value::Int64(val) => BigEndian::write_i64(buf, *val),
264            Value::Double(val) => BigEndian::write_f64(buf, *val),
265
266            Value::Text(val)
267            | Value::DateTime(val)
268            | Value::Date(val)
269            | Value::Time(val)
270            | Value::DecimalStr(val)
271            | Value::UserText(_, val) => buf[..val.len()].copy_from_slice(val.as_bytes()),
272
273            Value::Blob(val) | Value::UserBlob(_, val) => buf[..val.len()].copy_from_slice(val),
274
275            _ => unreachable!(),
276        }
277
278        // add [data] size to buffer and return it
279        let buf = &mut buf[data_size.or(fixed_size).unwrap()..];
280
281        Ok((buf, total_size))
282    }
283}
284
285impl<'a> TryFrom<&'a [u8]> for Value<'a> {
286    type Error = Error;
287
288    fn try_from(bytes: &'a [u8]) -> Result<Self> {
289        let data_type: Type = bytes.try_into()?;
290        let value = &bytes[data_type.size()..];
291
292        match data_type {
293            data_type::NULL => return Ok(Value::Null),
294            data_type::TRUE => return Ok(Value::True),
295            data_type::FALSE => return Ok(Value::False),
296            data_type::UINT8 => return Ok(Value::UInt8(utils::read_u8(value)?)),
297            data_type::INT8 => return Ok(Value::Int8(utils::read_i8(value)?)),
298            data_type::UINT16 => return Ok(Value::UInt16(utils::read_u16(value)?)),
299            data_type::INT16 => return Ok(Value::Int16(utils::read_i16(value)?)),
300            data_type::UINT32 => return Ok(Value::UInt32(utils::read_u32(value)?)),
301            data_type::INT32 => return Ok(Value::Int32(utils::read_i32(value)?)),
302            data_type::FLOAT => return Ok(Value::Float(utils::read_f32(value)?)),
303            data_type::UINT64 => return Ok(Value::UInt64(utils::read_u64(value)?)),
304            data_type::INT64 => return Ok(Value::Int64(utils::read_i64(value)?)),
305            data_type::DOUBLE => return Ok(Value::Double(utils::read_f64(value)?)),
306            data_type::TEXT => return Ok(Value::Text(utils::read_text(value)?)),
307            data_type::DATE_TIME => return Ok(Value::DateTime(utils::read_text(value)?)),
308            data_type::DATE => return Ok(Value::Date(utils::read_text(value)?)),
309            data_type::TIME => return Ok(Value::Time(utils::read_text(value)?)),
310            data_type::DECIMAL_STR => return Ok(Value::DecimalStr(utils::read_text(value)?)),
311            data_type::BLOB => return Ok(Value::Blob(utils::read_blob(value)?)),
312            Type {
313                storage: Storage::NoBytes,
314                subtype,
315            } => return Ok(Value::Empty(subtype)),
316            Type {
317                storage: Storage::Byte,
318                subtype,
319            } => return Ok(Value::Byte(subtype, utils::read_u8(value)?)),
320            Type {
321                storage: Storage::Word,
322                subtype,
323            } => return Ok(Value::Word(subtype, utils::read_u16(value)?)),
324            Type {
325                storage: Storage::DWord,
326                subtype,
327            } => return Ok(Value::DWord(subtype, utils::read_u32(value)?)),
328            Type {
329                storage: Storage::QWord,
330                subtype,
331            } => return Ok(Value::QWord(subtype, utils::read_u64(value)?)),
332            Type {
333                storage: Storage::String,
334                subtype,
335            } => return Ok(Value::UserText(subtype, utils::read_text(value)?)),
336            Type {
337                storage: Storage::Blob,
338                subtype,
339            } => return Ok(Value::UserBlob(subtype, utils::read_blob(value)?)),
340            // container storage is handled separately
341            Type {
342                storage: Storage::Container,
343                subtype: _,
344            } => {}
345        }
346        // all simple values handled, now deserialize container
347
348        match data_type {
349            data_type::LIST => Ok(Value::List(List {
350                inner: RawContainer::from_bytes(bytes, KeyType::Empty)?,
351            })),
352            data_type::MAP => Ok(Value::Map(Map {
353                inner: RawContainer::from_bytes(bytes, KeyType::Num)?,
354            })),
355            data_type::OBJECT => Ok(Value::Object(Object {
356                inner: RawContainer::from_bytes(bytes, KeyType::Str)?,
357            })),
358            Type {
359                storage: Storage::Container,
360                subtype: _,
361            } => Err(Error::Malformed),
362            _ => unreachable!(),
363        }
364    }
365}
366
367impl<'a> TryFrom<Value<'a>> for List<'a> {
368    type Error = Value<'a>;
369
370    fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
371        if let Value::List(list) = value {
372            Ok(list)
373        } else {
374            Err(value)
375        }
376    }
377}
378
379impl<'a> TryFrom<Value<'a>> for Map<'a> {
380    type Error = Value<'a>;
381
382    fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
383        if let Value::Map(map) = value {
384            Ok(map)
385        } else {
386            Err(value)
387        }
388    }
389}
390
391impl<'a> TryFrom<Value<'a>> for Object<'a> {
392    type Error = Value<'a>;
393
394    fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
395        if let Value::Object(obj) = value {
396            Ok(obj)
397        } else {
398            Err(value)
399        }
400    }
401}
402
403/// Helper trait to simplify conversions from normal types to value
404///
405/// Either as_ref or as_val must return Some
406pub trait AsValue<'a> {
407    fn to_value(self) -> Value<'a>;
408}
409
410impl<'a> AsValue<'a> for Value<'a> {
411    fn to_value(self) -> Value<'a> {
412        self
413    }
414}