nson/
decode.rs

1//! Decode
2
3use core::fmt;
4
5use alloc::format;
6use alloc::string::{FromUtf8Error, String};
7
8#[cfg(feature = "std")]
9use std::io::{self, Cursor, Read};
10
11#[cfg(not(feature = "std"))]
12use crate::io::{self, Cursor, Read};
13
14#[cfg(feature = "serde")]
15use crate::serde::decode::Decoder;
16#[cfg(feature = "serde")]
17use serde::de::Deserialize;
18
19use crate::array::Array;
20use crate::id::Id;
21use crate::map::Map;
22use crate::spec::DataType;
23use crate::value::{Binary, Value};
24
25#[derive(Debug)]
26pub enum DecodeError {
27    IoError(io::Error),
28    FromUtf8Error(FromUtf8Error),
29    UnrecognizedElementType(u8),
30    InvalidLength(usize, String),
31    Unknown(String),
32    #[cfg(feature = "serde")]
33    Serde(crate::serde::DecodeError),
34}
35
36impl From<io::Error> for DecodeError {
37    fn from(err: io::Error) -> DecodeError {
38        DecodeError::IoError(err)
39    }
40}
41
42impl From<FromUtf8Error> for DecodeError {
43    fn from(err: FromUtf8Error) -> DecodeError {
44        DecodeError::FromUtf8Error(err)
45    }
46}
47
48#[cfg(feature = "serde")]
49impl From<crate::serde::DecodeError> for DecodeError {
50    fn from(err: crate::serde::DecodeError) -> DecodeError {
51        DecodeError::Serde(err)
52    }
53}
54
55impl fmt::Display for DecodeError {
56    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
57        match *self {
58            DecodeError::IoError(ref inner) => inner.fmt(fmt),
59            DecodeError::FromUtf8Error(ref inner) => inner.fmt(fmt),
60            DecodeError::UnrecognizedElementType(tag) => {
61                write!(fmt, "Unrecognized element type `{}`", tag)
62            }
63            DecodeError::InvalidLength(ref len, ref desc) => {
64                write!(fmt, "Expecting length {}, {}", len, desc)
65            }
66            DecodeError::Unknown(ref inner) => inner.fmt(fmt),
67            #[cfg(feature = "serde")]
68            DecodeError::Serde(ref inner) => inner.fmt(fmt),
69        }
70    }
71}
72
73impl core::error::Error for DecodeError {
74    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
75        match *self {
76            DecodeError::IoError(ref inner) => Some(inner),
77            DecodeError::FromUtf8Error(ref inner) => Some(inner),
78            #[cfg(feature = "serde")]
79            DecodeError::Serde(ref inner) => Some(inner),
80            _ => None,
81        }
82    }
83}
84
85pub type DecodeResult<T> = Result<T, DecodeError>;
86
87#[inline]
88pub(crate) fn read_u8(reader: &mut impl Read) -> DecodeResult<u8> {
89    let mut buf = [0; 1];
90    reader.read_exact(&mut buf)?;
91    Ok(u8::from_le_bytes(buf))
92}
93
94#[inline]
95pub(crate) fn read_i8(reader: &mut impl Read) -> DecodeResult<i8> {
96    let mut buf = [0; 1];
97    reader.read_exact(&mut buf)?;
98    Ok(i8::from_le_bytes(buf))
99}
100
101#[inline]
102pub(crate) fn read_i16(reader: &mut impl Read) -> DecodeResult<i16> {
103    let mut buf = [0; 2];
104    reader.read_exact(&mut buf)?;
105    Ok(i16::from_le_bytes(buf))
106}
107
108#[inline]
109pub(crate) fn read_u16(reader: &mut impl Read) -> DecodeResult<u16> {
110    let mut buf = [0; 2];
111    reader.read_exact(&mut buf)?;
112    Ok(u16::from_le_bytes(buf))
113}
114
115#[inline]
116pub(crate) fn read_i32(reader: &mut impl Read) -> DecodeResult<i32> {
117    let mut buf = [0; 4];
118    reader.read_exact(&mut buf)?;
119    Ok(i32::from_le_bytes(buf))
120}
121
122#[inline]
123pub(crate) fn read_i64(reader: &mut impl Read) -> DecodeResult<i64> {
124    let mut buf = [0; 8];
125    reader.read_exact(&mut buf)?;
126    Ok(i64::from_le_bytes(buf))
127}
128
129#[inline]
130pub(crate) fn read_u32(reader: &mut impl Read) -> DecodeResult<u32> {
131    let mut buf = [0; 4];
132    reader.read_exact(&mut buf)?;
133    Ok(u32::from_le_bytes(buf))
134}
135
136#[inline]
137pub(crate) fn read_u64(reader: &mut impl Read) -> DecodeResult<u64> {
138    let mut buf = [0; 8];
139    reader.read_exact(&mut buf)?;
140    Ok(u64::from_le_bytes(buf))
141}
142
143#[inline]
144pub(crate) fn read_f32(reader: &mut impl Read) -> DecodeResult<f32> {
145    let mut buf = [0; 4];
146    reader.read_exact(&mut buf)?;
147    Ok(f32::from_le_bytes(buf))
148}
149
150#[inline]
151pub(crate) fn read_f64(reader: &mut impl Read) -> DecodeResult<f64> {
152    let mut buf = [0; 8];
153    reader.read_exact(&mut buf)?;
154    Ok(f64::from_le_bytes(buf))
155}
156
157pub(crate) fn read_string(reader: &mut impl Read) -> DecodeResult<String> {
158    let len = read_u32(reader)?;
159
160    if len < crate::MIN_NSON_SIZE - 1 {
161        return Err(DecodeError::InvalidLength(
162            len as usize,
163            format!("Invalid string length of {}", len),
164        ));
165    }
166
167    if len > crate::MAX_NSON_SIZE {
168        return Err(DecodeError::InvalidLength(
169            len as usize,
170            format!("Invalid string length of {}", len),
171        ));
172    }
173
174    let len = len - 4;
175
176    let mut buf = alloc::vec![0u8; len as usize];
177    reader.read_exact(&mut buf)?;
178
179    let s = String::from_utf8(buf)?;
180
181    Ok(s)
182}
183
184pub(crate) fn read_binary(reader: &mut impl Read) -> DecodeResult<Binary> {
185    let len = read_u32(reader)?;
186
187    if len < crate::MIN_NSON_SIZE - 1 {
188        return Err(DecodeError::InvalidLength(
189            len as usize,
190            format!("Invalid binary length of {}", len),
191        ));
192    }
193
194    if len > crate::MAX_NSON_SIZE {
195        return Err(DecodeError::InvalidLength(
196            len as usize,
197            format!("Invalid binary length of {}", len),
198        ));
199    }
200
201    let len = len - 4;
202
203    let mut data = alloc::vec![0u8; len as usize];
204    reader.read_exact(&mut data)?;
205
206    Ok(Binary(data))
207}
208
209pub fn decode_array(reader: &mut impl Read) -> DecodeResult<Array> {
210    let mut arr = Array::new();
211
212    let len = read_u32(reader)?;
213
214    if len < crate::MIN_NSON_SIZE {
215        return Err(DecodeError::InvalidLength(
216            len as usize,
217            format!("Invalid array length of {}", len),
218        ));
219    }
220
221    if len > crate::MAX_NSON_SIZE {
222        return Err(DecodeError::InvalidLength(
223            len as usize,
224            format!("Invalid array length of {}", len),
225        ));
226    }
227
228    loop {
229        let tag = read_u8(reader)?;
230        if tag == 0 {
231            break;
232        }
233
234        let val = decode_value_with_tag(reader, tag)?;
235        arr.push(val)
236    }
237
238    Ok(arr)
239}
240
241pub fn decode_map(reader: &mut impl Read) -> DecodeResult<Map> {
242    let mut map = Map::new();
243
244    // disregard the length: using Read::take causes infinite type recursion
245    let len = read_u32(reader)?;
246
247    if len < crate::MIN_NSON_SIZE {
248        return Err(DecodeError::InvalidLength(
249            len as usize,
250            format!("Invalid map length of {}", len),
251        ));
252    }
253
254    if len > crate::MAX_NSON_SIZE {
255        return Err(DecodeError::InvalidLength(
256            len as usize,
257            format!("Invalid map length of {}", len),
258        ));
259    }
260
261    loop {
262        let key = {
263            let len = read_u8(reader)?;
264            if len == 0 {
265                break;
266            }
267
268            let len = len - 1;
269
270            let mut buf = alloc::vec![0u8; len as usize];
271            reader.read_exact(&mut buf)?;
272
273            String::from_utf8(buf)?
274        };
275
276        let val = decode_value(reader)?;
277
278        map.insert(key, val);
279    }
280
281    Ok(map)
282}
283
284pub fn decode_value(reader: &mut impl Read) -> DecodeResult<Value> {
285    let tag = read_u8(reader)?;
286    decode_value_with_tag(reader, tag)
287}
288
289fn decode_value_with_tag(reader: &mut impl Read, tag: u8) -> DecodeResult<Value> {
290    match DataType::from(tag) {
291        Some(DataType::F32) => read_f32(reader).map(Value::F32),
292        Some(DataType::F64) => read_f64(reader).map(Value::F64),
293        Some(DataType::I32) => read_i32(reader).map(Value::I32),
294        Some(DataType::I64) => read_i64(reader).map(Value::I64),
295        Some(DataType::U32) => read_u32(reader).map(Value::U32),
296        Some(DataType::U64) => read_u64(reader).map(Value::U64),
297        Some(DataType::I8) => read_i8(reader).map(Value::I8),
298        Some(DataType::U8) => read_u8(reader).map(Value::U8),
299        Some(DataType::I16) => read_i16(reader).map(Value::I16),
300        Some(DataType::U16) => read_u16(reader).map(Value::U16),
301        Some(DataType::String) => read_string(reader).map(Value::String),
302        Some(DataType::Map) => decode_map(reader).map(Value::Map),
303        Some(DataType::Array) => decode_array(reader).map(Value::Array),
304        Some(DataType::Binary) => read_binary(reader).map(Value::Binary),
305        Some(DataType::Bool) => Ok(Value::Bool(crate::decode::read_u8(reader)? != 0)),
306        Some(DataType::Null) => Ok(Value::Null),
307        Some(DataType::TimeStamp) => read_u64(reader).map(|v| Value::TimeStamp(v.into())),
308        Some(DataType::Id) => {
309            let mut buf = [0; 12];
310            reader.read_exact(&mut buf)?;
311
312            Ok(Value::Id(Id::with_bytes(buf)))
313        }
314        None => Err(DecodeError::UnrecognizedElementType(tag)),
315    }
316}
317
318#[cfg(feature = "serde")]
319pub fn from_nson<'de, T: Deserialize<'de>>(value: Value) -> DecodeResult<T> {
320    let de = Decoder::new(value);
321    Deserialize::deserialize(de).map_err(DecodeError::Serde)
322}
323
324#[cfg(feature = "serde")]
325pub fn from_bytes<'de, T: Deserialize<'de>>(bytes: &[u8]) -> DecodeResult<T> {
326    let value = Value::from_bytes(bytes)?;
327    from_nson(value)
328}
329
330impl Value {
331    pub fn from_bytes(bytes: &[u8]) -> DecodeResult<Value> {
332        let mut reader = Cursor::new(bytes);
333        decode_value(&mut reader)
334    }
335}
336
337impl Map {
338    pub fn from_bytes(slice: &[u8]) -> DecodeResult<Map> {
339        let mut reader = Cursor::new(slice);
340        decode_map(&mut reader)
341    }
342}
343
344impl Array {
345    pub fn from_bytes(slice: &[u8]) -> DecodeResult<Array> {
346        let mut reader = Cursor::new(slice);
347        decode_array(&mut reader)
348    }
349}