Skip to main content

deser_msgpack/
de.rs

1use core::marker::PhantomData;
2
3use deser_core::Error;
4use deser_core::de::{self, Deserialize, DeserializeDriver};
5
6use crate::parser::{Borrowing, Parser, Progress, syntax_error};
7
8/// Configures how MessagePack is deserialized.
9///
10/// The configuration is independent of the input so it can be created once
11/// (even as a constant) and used for many inputs.  The method
12/// [`from_slice`](Self::from_slice) works like the function of the same
13/// name.  To read multiple items with the configuration create a
14/// [`Deserializer`] with [`Deserializer::from_slice_with_config`].
15///
16/// ```
17/// use deser_msgpack::DeserializerConfig;
18///
19/// const CONFIG: DeserializerConfig = DeserializerConfig::new();
20/// assert_eq!(CONFIG.from_slice::<Vec<u32>>(&[0x92, 0x01, 0x02]).unwrap(), [1, 2]);
21/// ```
22#[derive(Debug, Clone, Default, PartialEq, Eq)]
23pub struct DeserializerConfig {
24    // there are no options yet
25    _private: (),
26}
27
28impl DeserializerConfig {
29    /// Creates the default configuration.
30    pub const fn new() -> DeserializerConfig {
31        DeserializerConfig { _private: () }
32    }
33
34    /// Deserializes a value from MessagePack.
35    ///
36    /// See [`from_slice`](crate::from_slice).
37    pub fn from_slice<'de, T: Deserialize<'de>>(&self, input: &'de [u8]) -> Result<T, Error> {
38        let mut de = Deserializer::from_slice_with_config(input, self);
39        let rv = de.deserialize()?;
40        de.end()?;
41        Ok(rv)
42    }
43}
44
45/// Deserializes a deserializable from MessagePack.
46///
47/// A deserializer reads items from a slice.  Because MessagePack streams are
48/// just items following each other, a deserializer can be used to read more
49/// than one item:
50///
51/// ```
52/// use deser_msgpack::Deserializer;
53///
54/// let mut de = Deserializer::from_slice(&[0x01, 0xa2, b'h', b'i']);
55/// assert_eq!(de.deserialize::<u32>().unwrap(), 1);
56/// assert_eq!(de.deserialize::<String>().unwrap(), "hi");
57/// assert!(de.is_end());
58/// ```
59///
60/// To deserialize a single item, use [`from_slice`](crate::from_slice)
61/// (or the method of the same name on [`DeserializerConfig`]).
62pub struct Deserializer<'a> {
63    input: &'a [u8],
64    pos: usize,
65    config: DeserializerConfig,
66    parser: Parser,
67}
68
69impl<'a> Deserializer<'a> {
70    /// Creates a new deserializer for a byte slice.
71    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
72        Deserializer::from_slice_with_config(input, &DeserializerConfig::new())
73    }
74
75    /// Creates a new deserializer for a byte slice with the given
76    /// configuration.
77    pub fn from_slice_with_config(
78        input: &'a [u8],
79        config: &DeserializerConfig,
80    ) -> Deserializer<'a> {
81        Deserializer {
82            input,
83            pos: 0,
84            config: config.clone(),
85            parser: Parser::default(),
86        }
87    }
88
89    /// Returns the configuration.
90    pub fn config(&self) -> &DeserializerConfig {
91        &self.config
92    }
93
94    /// Returns the current offset in the input.
95    pub fn offset(&self) -> usize {
96        self.pos
97    }
98
99    /// Returns `true` if the entire input was consumed.
100    pub fn is_end(&self) -> bool {
101        self.pos >= self.input.len()
102    }
103
104    /// Fails if the input was not consumed entirely.
105    pub fn end(&self) -> Result<(), Error> {
106        if self.is_end() {
107            Ok(())
108        } else {
109            Err(syntax_error(self.pos, "trailing data after item"))
110        }
111    }
112
113    /// Deserializes the next item.
114    ///
115    /// This does not check if there is more data after the item.  Use
116    /// [`end`](Self::end) for this or [`from_slice`] which does it
117    /// automatically.
118    ///
119    /// To configure the deserialization (for instance to add layers) use
120    /// [`deserialize_with`](Self::deserialize_with).
121    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
122        de::Deserializer::deserialize(self)
123    }
124
125    /// Deserializes the next value with a configured driver.
126    ///
127    /// The callback is invoked with the driver before the value is
128    /// deserialized, for instance to add [`Layer`](deser_core::de::Layer)s.
129    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
130    where
131        T: Deserialize<'a>,
132        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
133    {
134        de::Deserializer::deserialize_with(self, setup)
135    }
136
137    /// Returns an iterator over the remaining items.
138    ///
139    /// This is useful to read streams of MessagePack items.  The iterator stops after
140    /// the first error.
141    ///
142    /// ```
143    /// let mut de = deser_msgpack::Deserializer::from_slice(&[0x01, 0x02, 0x03]);
144    /// let items = de.iter::<u32>().collect::<Result<Vec<_>, _>>().unwrap();
145    /// assert_eq!(items, [1, 2, 3]);
146    /// ```
147    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
148        Iter {
149            de: self,
150            failed: false,
151            _marker: PhantomData,
152        }
153    }
154
155    /// Parses the next item and feeds the events into the given driver.
156    ///
157    /// This is useful to deserialize into a custom
158    /// [`Sink`](deser_core::de::Sink) or to wrap the sink of a value.
159    ///
160    /// Strings and binary data are passed on borrowed from the input (see
161    /// [`emit_borrowed`](DeserializeDriver::emit_borrowed)).  The byte
162    /// ranges of the items are published as input ranges (see
163    /// [`State::input_range`](deser_core::State::input_range)) and errors carry
164    /// the offset in the input (see [`Error::offset`]).
165    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
166        match self
167            .parser
168            .parse(self.input, self.pos, true, 0, &mut Borrowing(driver))
169        {
170            Ok(Progress::Done(pos)) => {
171                self.pos = pos;
172                Ok(())
173            }
174            Ok(Progress::NeedMore(_)) => unreachable!("the input is complete"),
175            Err(err) => {
176                // the next item is read from where the parser stopped
177                self.pos = self.parser.position();
178                self.parser.reset();
179                Err(err)
180            }
181        }
182    }
183}
184
185/// An iterator over the items of a MessagePack stream.
186///
187/// See [`Deserializer::iter`].
188pub struct Iter<'b, 'a, T> {
189    de: &'b mut Deserializer<'a>,
190    failed: bool,
191    _marker: PhantomData<fn() -> T>,
192}
193
194impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
195    type Item = Result<T, Error>;
196
197    fn next(&mut self) -> Option<Self::Item> {
198        if self.failed || self.de.is_end() {
199            return None;
200        }
201        let rv = self.de.deserialize();
202        self.failed = rv.is_err();
203        Some(rv)
204    }
205}
206
207impl<'a> de::Deserializer<'a> for Deserializer<'a> {
208    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
209        Deserializer::drive(self, driver)
210    }
211}
212
213/// Deserializes a value from MessagePack.
214///
215/// The input must contain exactly one item.  This uses the default
216/// [`DeserializerConfig`].
217pub fn from_slice<'de, T: Deserialize<'de>>(input: &'de [u8]) -> Result<T, Error> {
218    DeserializerConfig::new().from_slice(input)
219}