Skip to main content

deser_msgpack/
de.rs

1use core::marker::PhantomData;
2
3use deser_core::Error;
4use deser_core::de::{self, Deserialize, DeserializeDriver, deserialize_value};
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    context: deser_core::Context,
25}
26
27impl DeserializerConfig {
28    /// Creates the default configuration.
29    pub const fn new() -> DeserializerConfig {
30        DeserializerConfig {
31            context: deser_core::Context::new(),
32        }
33    }
34
35    /// Returns a builder for the configuration (see [`DeserializerConfigBuilder`]).
36    pub const fn builder() -> DeserializerConfigBuilder {
37        DeserializerConfigBuilder::new()
38    }
39
40    /// Returns a builder that starts with this configuration.
41    pub const fn into_builder(self) -> DeserializerConfigBuilder {
42        DeserializerConfigBuilder { value: self }
43    }
44
45    /// Sets the context the values are deserialized in.
46    ///
47    /// The values of the context are the defaults of the extension values
48    /// of the state (see [`Context`](deser_core::Context)), for instance
49    /// the variants of open enums.  The deserializers and readers created
50    /// with the configuration use this context.  A context set
51    /// on the driver takes precedence.
52    pub fn set_context(&mut self, context: deser_core::Context) {
53        self.context = context;
54    }
55
56    /// Returns the configuration without its context (for the frames of
57    /// streams, which get the context of the stream).
58    pub(crate) fn without_context(&self) -> DeserializerConfig {
59        let mut config = self.clone();
60        config.context = deser_core::Context::default();
61        config
62    }
63
64    /// Returns the context the values are deserialized in.
65    pub fn context(&self) -> &deser_core::Context {
66        &self.context
67    }
68
69    /// Deserializes a value from MessagePack.
70    ///
71    /// See [`from_slice`].
72    pub fn from_slice<'de, T: Deserialize<'de>>(&self, input: &'de [u8]) -> Result<T, Error> {
73        deserialize_value(|driver| self.drive_slice(input, driver))
74    }
75
76    /// The part of [`from_slice`](Self::from_slice) that does not depend on
77    /// the type of the value, it exists once.
78    fn drive_slice<'de>(
79        &self,
80        input: &'de [u8],
81        driver: &mut DeserializeDriver<'_, 'de>,
82    ) -> Result<(), Error> {
83        let mut deserializer = Deserializer::from_slice_with_config(input, self.clone());
84        de::Deserializer::drive(&mut deserializer, driver)?;
85        deserializer.end()
86    }
87}
88
89/// Builds a [`DeserializerConfig`].
90///
91/// The methods have the names of the setters of [`DeserializerConfig`] (without `set_`).
92#[derive(Debug, Clone)]
93#[must_use]
94pub struct DeserializerConfigBuilder {
95    value: DeserializerConfig,
96}
97
98impl DeserializerConfigBuilder {
99    /// Creates a builder that starts with the default.
100    pub const fn new() -> DeserializerConfigBuilder {
101        DeserializerConfigBuilder {
102            value: DeserializerConfig::new(),
103        }
104    }
105
106    /// Sets the context the values are deserialized in.
107    ///
108    /// See [`DeserializerConfig::set_context`].
109    pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
110        self.value.set_context(context);
111        self
112    }
113
114    /// Returns the built [`DeserializerConfig`].
115    pub const fn build(self) -> DeserializerConfig {
116        // the value cannot be moved out of the builder in a const fn as the
117        // builder needs dropping (the context has a destructor)
118        // SAFETY: the value is read once and the builder is forgotten
119        let value = unsafe { core::ptr::read(&self.value) };
120        core::mem::forget(self);
121        value
122    }
123}
124
125impl Default for DeserializerConfigBuilder {
126    fn default() -> DeserializerConfigBuilder {
127        DeserializerConfigBuilder::new()
128    }
129}
130
131/// Deserializes a deserializable from MessagePack.
132///
133/// A deserializer reads items from a slice.  Because MessagePack streams are
134/// just items following each other, a deserializer can be used to read more
135/// than one item:
136///
137/// ```
138/// use deser_msgpack::Deserializer;
139///
140/// let mut de = Deserializer::from_slice(&[0x01, 0xa2, b'h', b'i']);
141/// assert_eq!(de.deserialize::<u32>().unwrap(), 1);
142/// assert_eq!(de.deserialize::<String>().unwrap(), "hi");
143/// assert!(de.is_end());
144/// ```
145///
146/// To deserialize a single item, use [`from_slice`]
147/// (or the method of the same name on [`DeserializerConfig`]).
148pub struct Deserializer<'a> {
149    input: &'a [u8],
150    pos: usize,
151    config: DeserializerConfig,
152    parser: Parser,
153}
154
155impl<'a> Deserializer<'a> {
156    /// Creates a new deserializer for a byte slice.
157    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
158        Deserializer::from_slice_with_config(input, DeserializerConfig::new())
159    }
160
161    /// Creates a new deserializer for a byte slice with the given
162    /// configuration.
163    pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
164        Deserializer {
165            input,
166            pos: 0,
167            config,
168            parser: Parser::default(),
169        }
170    }
171
172    /// Returns the configuration.
173    pub fn config(&self) -> &DeserializerConfig {
174        &self.config
175    }
176
177    /// Returns the current offset in the input.
178    pub fn offset(&self) -> usize {
179        self.pos
180    }
181
182    /// Returns `true` if the entire input was consumed.
183    pub fn is_end(&self) -> bool {
184        self.pos >= self.input.len()
185    }
186
187    /// Fails if the input was not consumed entirely.
188    pub fn end(&self) -> Result<(), Error> {
189        if self.is_end() {
190            Ok(())
191        } else {
192            Err(syntax_error(self.pos, "trailing data after item"))
193        }
194    }
195
196    /// Deserializes the next item.
197    ///
198    /// This does not check if there is more data after the item.  Use
199    /// [`end`](Self::end) for this or [`from_slice`] which does it
200    /// automatically.
201    ///
202    /// To configure the deserialization (for instance to add layers) use
203    /// [`deserialize_with`](Self::deserialize_with).
204    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
205        de::Deserializer::deserialize(self)
206    }
207
208    /// Deserializes the next value with a configured driver.
209    ///
210    /// The callback is invoked with the driver before the value is
211    /// deserialized, for instance to add [`Layer`](deser_core::de::Layer)s.
212    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
213    where
214        T: Deserialize<'a>,
215        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
216    {
217        de::Deserializer::deserialize_with(self, setup)
218    }
219
220    /// Returns an iterator over the remaining items.
221    ///
222    /// This is useful to read streams of MessagePack items.  The iterator stops after
223    /// the first error.
224    ///
225    /// ```
226    /// let mut de = deser_msgpack::Deserializer::from_slice(&[0x01, 0x02, 0x03]);
227    /// let items = de.iter::<u32>().collect::<Result<Vec<_>, _>>().unwrap();
228    /// assert_eq!(items, [1, 2, 3]);
229    /// ```
230    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
231        Iter {
232            de: self,
233            failed: false,
234            _marker: PhantomData,
235        }
236    }
237
238    /// Parses the next item and feeds the events into the given driver.
239    ///
240    /// This is useful to deserialize into a custom
241    /// [`Sink`](deser_core::de::Sink) or to wrap the sink of a value.
242    ///
243    /// Strings and binary data are passed on borrowed from the input (see
244    /// [`emit_borrowed`](DeserializeDriver::emit_borrowed)).  The byte
245    /// ranges of the items are published as input ranges (see
246    /// [`State::input_range`](deser_core::State::input_range)) and errors carry
247    /// the offset in the input (see [`Error::offset`]).
248    ///
249    /// The context of the configuration is given to the driver (values that
250    /// the context of the driver has take precedence, see
251    /// [`DeserializeDriver::set_default_context`]).
252    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
253        if !self.config.context.is_empty() {
254            driver.set_default_context(self.config.context.clone());
255        }
256        match self
257            .parser
258            .parse(self.input, self.pos, true, 0, &mut Borrowing(driver))
259        {
260            Ok(Progress::Done(pos)) => {
261                self.pos = pos;
262                Ok(())
263            }
264            Ok(Progress::NeedMore(_)) => unreachable!("the input is complete"),
265            Err(err) => {
266                // the next item is read from where the parser stopped
267                self.pos = self.parser.position();
268                self.parser.reset();
269                Err(err)
270            }
271        }
272    }
273}
274
275/// An iterator over the items of a MessagePack stream.
276///
277/// See [`Deserializer::iter`].
278pub struct Iter<'b, 'a, T> {
279    de: &'b mut Deserializer<'a>,
280    failed: bool,
281    _marker: PhantomData<fn() -> T>,
282}
283
284impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
285    type Item = Result<T, Error>;
286
287    fn next(&mut self) -> Option<Self::Item> {
288        if self.failed || self.de.is_end() {
289            return None;
290        }
291        let rv = self.de.deserialize();
292        self.failed = rv.is_err();
293        Some(rv)
294    }
295}
296
297impl<'a> de::Deserializer<'a> for Deserializer<'a> {
298    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
299        Deserializer::drive(self, driver)
300    }
301}
302
303/// Deserializes a value from MessagePack.
304///
305/// The input must contain exactly one item.  This uses the default
306/// [`DeserializerConfig`].
307pub fn from_slice<'de, T: Deserialize<'de>>(input: &'de [u8]) -> Result<T, Error> {
308    DeserializerConfig::new().from_slice(input)
309}