lilliput_core/
encoder.rs

1//! Encoders for encoding lilliput values.
2
3use crate::{config::EncoderConfig, error::Result, header::Header, io::Write, value::Value};
4
5mod bool;
6mod bytes;
7mod float;
8mod int;
9mod map;
10mod null;
11mod seq;
12mod string;
13mod unit;
14
15/// An encoder for encoding lilliput values.
16#[derive(Debug)]
17pub struct Encoder<W> {
18    writer: W,
19    pos: usize,
20    config: EncoderConfig,
21}
22
23impl<W> Encoder<W> {
24    /// Creates a encoder from `writer`.
25    pub fn from_writer(writer: W) -> Self {
26        Self::new(writer, EncoderConfig::default())
27    }
28
29    /// Creates a encoder from `writer`, configured by `config`.
30    pub fn new(writer: W, config: EncoderConfig) -> Self {
31        Encoder {
32            writer,
33            pos: 0,
34            config,
35        }
36    }
37
38    /// Returns the encoder's internal `writer`, consuming `self`.
39    pub fn into_writer(self) -> W {
40        self.writer
41    }
42
43    /// Returns the encoder's current write position.
44    pub fn pos(&self) -> usize {
45        self.pos
46    }
47}
48
49impl<W> Encoder<W>
50where
51    W: Write,
52{
53    /// Encodes a value's `Header`.
54    pub fn encode_header(&mut self, header: &Header) -> Result<()> {
55        match header {
56            Header::Int(value) => self.encode_int_header(value),
57            Header::String(value) => self.encode_string_header(value),
58            Header::Seq(value) => self.encode_seq_header(value),
59            Header::Map(value) => self.encode_map_header(value),
60            Header::Float(value) => self.encode_float_header(value),
61            Header::Bytes(value) => self.encode_bytes_header(value),
62            Header::Bool(value) => self.encode_bool_header(value),
63            Header::Unit(value) => self.encode_unit_header(value),
64            Header::Null(value) => self.encode_null_header(value),
65        }
66    }
67
68    /// Encodes a `Value`.
69    pub fn encode_value(&mut self, value: &Value) -> Result<()> {
70        match value {
71            Value::Int(value) => self.encode_int_value(value),
72            Value::String(value) => self.encode_string_value(value),
73            Value::Seq(value) => self.encode_seq_value(value),
74            Value::Map(value) => self.encode_map_value(value),
75            Value::Float(value) => self.encode_float_value(value),
76            Value::Bytes(value) => self.encode_bytes_value(value),
77            Value::Bool(value) => self.encode_bool_value(value),
78            Value::Unit(value) => self.encode_unit_value(value),
79            Value::Null(value) => self.encode_null_value(value),
80        }
81    }
82}
83
84// MARK: - Auxiliary Methods
85
86impl<W> Encoder<W>
87where
88    W: Write,
89{
90    #[inline]
91    fn push_byte(&mut self, byte: u8) -> Result<()> {
92        self.push_bytes(&[byte])
93    }
94
95    fn push_bytes(&mut self, bytes: &[u8]) -> Result<()> {
96        self.writer.write(bytes)?;
97        self.pos += bytes.len();
98
99        Ok(())
100    }
101}
102
103// MARK: - Tests
104
105#[cfg(test)]
106mod test {
107    use crate::io::{StdIoWriter, VecWriter};
108
109    use super::*;
110
111    #[test]
112    fn push_bytes() {
113        let mut vec: Vec<u8> = Vec::new();
114        let writer = VecWriter::new(&mut vec);
115        let mut encoder = Encoder::from_writer(writer);
116
117        encoder.push_bytes(&[]).unwrap();
118        encoder.push_bytes(&[1]).unwrap();
119        encoder.push_bytes(&[2, 3]).unwrap();
120
121        assert_eq!(vec, vec![1, 2, 3]);
122    }
123
124    #[test]
125    fn into_vec() {
126        let mut vec: Vec<u8> = Vec::new();
127        let writer = StdIoWriter::new(&mut vec);
128        let mut encoder = Encoder::from_writer(writer);
129        encoder.push_bytes(&[1, 2, 3]).unwrap();
130
131        assert_eq!(vec, vec![1, 2, 3]);
132    }
133}