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