nson/
encode.rs

1//! Encode
2
3use core::fmt;
4
5use alloc::string::{String, ToString};
6use alloc::vec::Vec;
7
8#[cfg(feature = "std")]
9use std::io::{self, Write};
10
11#[cfg(not(feature = "std"))]
12use crate::io::{self, Write};
13
14#[cfg(feature = "serde")]
15use crate::serde::encode::Encoder;
16#[cfg(feature = "serde")]
17use serde::ser::Serialize;
18
19use crate::array::Array;
20use crate::map::Map;
21use crate::value::{Binary, Value};
22
23#[derive(Debug)]
24#[non_exhaustive]
25pub enum EncodeError {
26    IoError(io::Error),
27    InvalidKeyLen(usize, String),
28    InvalidValueLen(usize, String),
29    Unknown(String),
30    #[cfg(feature = "serde")]
31    Serde(crate::serde::EncodeError),
32}
33
34impl From<io::Error> for EncodeError {
35    fn from(err: io::Error) -> EncodeError {
36        EncodeError::IoError(err)
37    }
38}
39
40#[cfg(feature = "serde")]
41impl From<crate::serde::EncodeError> for EncodeError {
42    fn from(err: crate::serde::EncodeError) -> EncodeError {
43        EncodeError::Serde(err)
44    }
45}
46
47impl fmt::Display for EncodeError {
48    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
49        match *self {
50            EncodeError::IoError(ref inner) => inner.fmt(fmt),
51            EncodeError::InvalidKeyLen(ref len, ref desc) => {
52                write!(fmt, "Invalid key len: {}, {}", len, desc)
53            }
54            EncodeError::InvalidValueLen(ref len, ref desc) => {
55                write!(fmt, "Invalid value len: {}, {}", len, desc)
56            }
57            EncodeError::Unknown(ref inner) => inner.fmt(fmt),
58            #[cfg(feature = "serde")]
59            EncodeError::Serde(ref inner) => inner.fmt(fmt),
60        }
61    }
62}
63
64impl core::error::Error for EncodeError {
65    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
66        match *self {
67            EncodeError::IoError(ref inner) => Some(inner),
68            #[cfg(feature = "serde")]
69            EncodeError::Serde(ref inner) => Some(inner),
70            _ => None,
71        }
72    }
73}
74
75pub type EncodeResult<T> = Result<T, EncodeError>;
76
77#[inline]
78pub(crate) fn write_i8(writer: &mut impl Write, val: i8) -> EncodeResult<()> {
79    writer.write_all(&val.to_le_bytes()).map_err(From::from)
80}
81
82#[inline]
83pub(crate) fn write_u8(writer: &mut impl Write, val: u8) -> EncodeResult<()> {
84    writer.write_all(&val.to_le_bytes()).map_err(From::from)
85}
86
87#[inline]
88pub(crate) fn write_i16(writer: &mut impl Write, val: i16) -> EncodeResult<()> {
89    writer.write_all(&val.to_le_bytes()).map_err(From::from)
90}
91
92#[inline]
93pub(crate) fn write_u16(writer: &mut impl Write, val: u16) -> EncodeResult<()> {
94    writer.write_all(&val.to_le_bytes()).map_err(From::from)
95}
96
97#[inline]
98pub(crate) fn write_i32(writer: &mut impl Write, val: i32) -> EncodeResult<()> {
99    writer.write_all(&val.to_le_bytes()).map_err(From::from)
100}
101
102#[inline]
103pub(crate) fn write_u32(writer: &mut impl Write, val: u32) -> EncodeResult<()> {
104    writer.write_all(&val.to_le_bytes()).map_err(From::from)
105}
106
107#[inline]
108pub(crate) fn write_i64(writer: &mut impl Write, val: i64) -> EncodeResult<()> {
109    writer.write_all(&val.to_le_bytes()).map_err(From::from)
110}
111
112#[inline]
113pub(crate) fn write_u64(writer: &mut impl Write, val: u64) -> EncodeResult<()> {
114    writer.write_all(&val.to_le_bytes()).map_err(From::from)
115}
116
117#[inline]
118pub(crate) fn write_f32(writer: &mut impl Write, val: f32) -> EncodeResult<()> {
119    writer.write_all(&val.to_le_bytes()).map_err(From::from)
120}
121
122#[inline]
123pub(crate) fn write_f64(writer: &mut impl Write, val: f64) -> EncodeResult<()> {
124    writer.write_all(&val.to_le_bytes()).map_err(From::from)
125}
126
127pub(crate) fn write_key(writer: &mut impl Write, s: &str) -> EncodeResult<()> {
128    if s.is_empty() || s.len() >= u8::MAX as usize {
129        return Err(EncodeError::InvalidKeyLen(
130            s.len(),
131            "key len must > 0 and < 255".to_string(),
132        ));
133    }
134
135    writer.write_all(&[s.len() as u8 + 1])?;
136    writer.write_all(s.as_bytes())?;
137    Ok(())
138}
139
140pub(crate) fn write_string(writer: &mut impl Write, s: &str) -> EncodeResult<()> {
141    if s.len() > crate::MAX_NSON_SIZE as usize - 4 {
142        return Err(EncodeError::InvalidValueLen(
143            s.len(),
144            "string len must < MAX_NSON_SIZE - 4".to_string(),
145        ));
146    }
147
148    write_u32(writer, s.len() as u32 + 4)?;
149    writer.write_all(s.as_bytes())?;
150    Ok(())
151}
152
153pub(crate) fn write_binary(writer: &mut impl Write, binary: &Binary) -> EncodeResult<()> {
154    if binary.0.len() > crate::MAX_NSON_SIZE as usize - 4 {
155        return Err(EncodeError::InvalidValueLen(
156            binary.0.len(),
157            "binary len must < MAX_NSON_SIZE - 4".to_string(),
158        ));
159    }
160
161    write_u32(writer, binary.0.len() as u32 + 4)?;
162    writer.write_all(&binary.0)?;
163    Ok(())
164}
165
166pub fn encode_array(writer: &mut impl Write, array: &Array) -> EncodeResult<()> {
167    let len = array.bytes_size();
168
169    if len > crate::MAX_NSON_SIZE as usize {
170        return Err(EncodeError::InvalidValueLen(
171            len,
172            "array len must < MAX_NSON_SIZE".to_string(),
173        ));
174    }
175
176    write_u32(writer, len as u32)?;
177
178    for val in array.iter() {
179        encode_value(writer, val)?;
180    }
181
182    writer.write_all(&[0])?;
183
184    Ok(())
185}
186
187pub fn encode_map(writer: &mut impl Write, map: &Map) -> EncodeResult<()> {
188    let len = map.bytes_size();
189
190    if len > crate::MAX_NSON_SIZE as usize {
191        return Err(EncodeError::InvalidValueLen(
192            len,
193            "map len must < MAX_NSON_SIZE".to_string(),
194        ));
195    }
196
197    write_u32(writer, len as u32)?;
198
199    for (key, val) in map {
200        write_key(writer, key)?;
201
202        encode_value(writer, val)?;
203    }
204
205    writer.write_all(&[0])?;
206
207    Ok(())
208}
209
210pub fn encode_value(writer: &mut impl Write, val: &Value) -> EncodeResult<()> {
211    writer.write_all(&[val.element_type() as u8])?;
212
213    match *val {
214        Value::F32(v) => write_f32(writer, v),
215        Value::F64(v) => write_f64(writer, v),
216        Value::I32(v) => write_i32(writer, v),
217        Value::I64(v) => write_i64(writer, v),
218        Value::U32(v) => write_u32(writer, v),
219        Value::U64(v) => write_u64(writer, v),
220        Value::I8(v) => write_i8(writer, v),
221        Value::U8(v) => write_u8(writer, v),
222        Value::I16(v) => write_i16(writer, v),
223        Value::U16(v) => write_u16(writer, v),
224        Value::String(ref s) => write_string(writer, s),
225        Value::Array(ref a) => encode_array(writer, a),
226        Value::Map(ref o) => encode_map(writer, o),
227        Value::Bool(b) => writer
228            .write_all(&[if b { 0x01 } else { 0x00 }])
229            .map_err(From::from),
230        Value::Null => Ok(()),
231        Value::Binary(ref binary) => write_binary(writer, binary),
232        Value::TimeStamp(v) => write_u64(writer, v.0),
233        Value::Id(ref id) => writer.write_all(&id.bytes()).map_err(From::from),
234    }
235}
236
237impl Value {
238    pub fn to_bytes(&self) -> EncodeResult<Vec<u8>> {
239        let mut buf = Vec::new();
240        encode_value(&mut buf, self)?;
241        Ok(buf)
242    }
243}
244
245impl Map {
246    pub fn to_bytes(&self) -> EncodeResult<Vec<u8>> {
247        let len = self.bytes_size();
248
249        if len > crate::MAX_NSON_SIZE as usize {
250            return Err(EncodeError::InvalidValueLen(
251                len,
252                "map len must < MAX_NSON_SIZE".to_string(),
253            ));
254        }
255
256        let mut buf = Vec::with_capacity(len);
257        write_u32(&mut buf, len as u32)?;
258
259        for (key, val) in self {
260            write_key(&mut buf, key)?;
261
262            encode_value(&mut buf, val)?;
263        }
264
265        buf.write_all(&[0])?;
266
267        Ok(buf)
268    }
269}
270
271impl Array {
272    pub fn to_bytes(&self) -> EncodeResult<Vec<u8>> {
273        let len = self.bytes_size();
274
275        if len > crate::MAX_NSON_SIZE as usize {
276            return Err(EncodeError::InvalidValueLen(
277                len,
278                "array len must < MAX_NSON_SIZE".to_string(),
279            ));
280        }
281
282        let mut buf = Vec::with_capacity(len);
283        write_u32(&mut buf, len as u32)?;
284
285        for val in self.iter() {
286            encode_value(&mut buf, val)?;
287        }
288
289        buf.write_all(&[0])?;
290
291        Ok(buf)
292    }
293}
294
295#[cfg(feature = "serde")]
296pub fn to_nson<T: Serialize + ?Sized>(value: &T) -> EncodeResult<Value> {
297    let ser = Encoder::new();
298    value.serialize(ser).map_err(EncodeError::Serde)
299}
300
301#[cfg(feature = "serde")]
302pub fn to_bytes<T: Serialize + ?Sized>(value: &T) -> EncodeResult<Vec<u8>> {
303    let value = to_nson(value)?;
304    value.to_bytes()
305}
306
307#[cfg(test)]
308mod test {
309    use crate::decode::decode_map;
310    use crate::encode::encode_map;
311    use crate::m;
312
313    use alloc::vec::Vec;
314
315    #[cfg(feature = "std")]
316    use std::io::Cursor;
317
318    #[cfg(not(feature = "std"))]
319    use crate::io::Cursor;
320
321    #[test]
322    fn encode() {
323        let m = m! {"aa": "bb", "cc": [1, 2, 3, 4]};
324
325        let mut buf: Vec<u8> = Vec::new();
326
327        encode_map(&mut buf, &m).unwrap();
328
329        let mut reader = Cursor::new(buf);
330
331        let m2 = decode_map(&mut reader).unwrap();
332
333        assert_eq!(m, m2);
334    }
335}