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