creator_plist/
de.rs

1use serde::de;
2use std::{
3    fmt::Display,
4    fs::File,
5    io::{BufReader, Cursor, Read, Seek},
6    iter::Peekable,
7    mem,
8    path::Path,
9};
10
11use crate::{
12    error::{self, Error, ErrorKind, EventKind},
13    stream::{self, Event},
14    u64_to_usize,
15};
16
17macro_rules! expect {
18    ($next:expr, $kind:expr) => {
19        match $next {
20            Some(Ok(ref event)) if EventKind::of_event(event) != $kind => {
21                return Err(error::unexpected_event_type($kind, event))?;
22            }
23            Some(Ok(event)) => event,
24            Some(Err(err)) => return Err(err),
25            None => return Err(ErrorKind::UnexpectedEndOfEventStream.without_position()),
26        }
27    };
28}
29
30macro_rules! try_next {
31    ($next:expr) => {
32        match $next {
33            Some(Ok(event)) => event,
34            Some(Err(err)) => return Err(err)?,
35            None => return Err(ErrorKind::UnexpectedEndOfEventStream.without_position())?,
36        }
37    };
38}
39
40#[doc(hidden)]
41impl de::Error for Error {
42    fn custom<T: Display>(msg: T) -> Self {
43        ErrorKind::Serde(msg.to_string()).without_position()
44    }
45}
46
47#[allow(dead_code)]
48enum OptionMode {
49    Root,
50    StructField,
51    Explicit,
52}
53
54impl Default for OptionMode {
55    fn default() -> Self {
56        Self::Root
57    }
58}
59
60/// A structure that deserializes plist event streams into Rust values.
61pub struct Deserializer<I>
62where
63    I: IntoIterator<Item = Result<Event, Error>>,
64{
65    events: Peekable<<I as IntoIterator>::IntoIter>,
66    option_mode: OptionMode,
67}
68
69impl<I> Deserializer<I>
70where
71    I: IntoIterator<Item = Result<Event, Error>>,
72{
73    pub fn new(iter: I) -> Deserializer<I> {
74        Deserializer {
75            events: iter.into_iter().peekable(),
76            option_mode: OptionMode::Root,
77        }
78    }
79
80    fn with_option_mode<T, F: FnOnce(&mut Deserializer<I>) -> Result<T, Error>>(
81        &mut self,
82        option_mode: OptionMode,
83        f: F,
84    ) -> Result<T, Error> {
85        let prev_option_mode = mem::replace(&mut self.option_mode, option_mode);
86        let ret = f(&mut *self);
87        self.option_mode = prev_option_mode;
88        ret
89    }
90}
91
92impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer<I>
93where
94    I: IntoIterator<Item = Result<Event, Error>>,
95{
96    type Error = Error;
97
98    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
99    where
100        V: de::Visitor<'de>,
101    {
102        match try_next!(self.events.next()) {
103            Event::StartArray(len) => {
104                let len = len.and_then(u64_to_usize);
105                let ret = visitor.visit_seq(MapAndSeqAccess::new(self, false, len))?;
106                expect!(self.events.next(), EventKind::EndCollection);
107                Ok(ret)
108            }
109            Event::StartDictionary(len) => {
110                let len = len.and_then(u64_to_usize);
111                let ret = visitor.visit_map(MapAndSeqAccess::new(self, false, len))?;
112                expect!(self.events.next(), EventKind::EndCollection);
113                Ok(ret)
114            }
115            event @ Event::EndCollection => Err(error::unexpected_event_type(
116                EventKind::ValueOrStartCollection,
117                &event,
118            )),
119
120            Event::Boolean(v) => visitor.visit_bool(v),
121            Event::Data(v) => visitor.visit_byte_buf(v),
122            Event::Date(v) => visitor.visit_string(v.to_rfc3339()),
123            Event::Integer(v) => {
124                if let Some(v) = v.as_unsigned() {
125                    visitor.visit_u64(v)
126                } else if let Some(v) = v.as_signed() {
127                    visitor.visit_i64(v)
128                } else {
129                    unreachable!()
130                }
131            }
132            Event::Real(v) => visitor.visit_f64(v),
133            Event::String(v) => visitor.visit_string(v),
134            Event::Uid(v) => visitor.visit_u64(v.get()),
135
136            Event::__Nonexhaustive => unreachable!(),
137        }
138    }
139
140    forward_to_deserialize_any! {
141        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string
142        seq bytes byte_buf map unit_struct
143        tuple_struct tuple ignored_any identifier
144    }
145
146    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
147    where
148        V: de::Visitor<'de>,
149    {
150        expect!(self.events.next(), EventKind::String);
151        visitor.visit_unit()
152    }
153
154    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
155    where
156        V: de::Visitor<'de>,
157    {
158        match self.option_mode {
159            OptionMode::Root => {
160                if self.events.peek().is_none() {
161                    visitor.visit_none::<Error>()
162                } else {
163                    self.with_option_mode(OptionMode::default(), |this| visitor.visit_some(this))
164                }
165            }
166            OptionMode::StructField => {
167                // None struct values are ignored so if we're here the value must be Some.
168                self.with_option_mode(OptionMode::default(), |this| Ok(visitor.visit_some(this)?))
169            }
170            OptionMode::Explicit => {
171                expect!(self.events.next(), EventKind::StartDictionary);
172
173                let ret = match try_next!(self.events.next()) {
174                    Event::String(ref s) if &s[..] == "None" => {
175                        expect!(self.events.next(), EventKind::String);
176                        visitor.visit_none::<Error>()?
177                    }
178                    Event::String(ref s) if &s[..] == "Some" => visitor.visit_some(&mut *self)?,
179                    event => return Err(error::unexpected_event_type(EventKind::String, &event))?,
180                };
181
182                expect!(self.events.next(), EventKind::EndCollection);
183
184                Ok(ret)
185            }
186        }
187    }
188
189    fn deserialize_newtype_struct<V>(
190        self,
191        _name: &'static str,
192        visitor: V,
193    ) -> Result<V::Value, Error>
194    where
195        V: de::Visitor<'de>,
196    {
197        visitor.visit_newtype_struct(self)
198    }
199
200    fn deserialize_struct<V>(
201        self,
202        _name: &'static str,
203        _fields: &'static [&'static str],
204        visitor: V,
205    ) -> Result<V::Value, Error>
206    where
207        V: de::Visitor<'de>,
208    {
209        expect!(self.events.next(), EventKind::StartDictionary);
210        let ret = visitor.visit_map(MapAndSeqAccess::new(self, true, None))?;
211        expect!(self.events.next(), EventKind::EndCollection);
212        Ok(ret)
213    }
214
215    fn deserialize_enum<V>(
216        self,
217        _enum: &'static str,
218        _variants: &'static [&'static str],
219        visitor: V,
220    ) -> Result<V::Value, Error>
221    where
222        V: de::Visitor<'de>,
223    {
224        expect!(self.events.next(), EventKind::StartDictionary);
225        let ret = visitor.visit_enum(&mut *self)?;
226        expect!(self.events.next(), EventKind::EndCollection);
227        Ok(ret)
228    }
229}
230
231impl<'de, 'a, I> de::EnumAccess<'de> for &'a mut Deserializer<I>
232where
233    I: IntoIterator<Item = Result<Event, Error>>,
234{
235    type Error = Error;
236    type Variant = Self;
237
238    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error>
239    where
240        V: de::DeserializeSeed<'de>,
241    {
242        Ok((seed.deserialize(&mut *self)?, self))
243    }
244}
245
246impl<'de, 'a, I> de::VariantAccess<'de> for &'a mut Deserializer<I>
247where
248    I: IntoIterator<Item = Result<Event, Error>>,
249{
250    type Error = Error;
251
252    fn unit_variant(self) -> Result<(), Error> {
253        de::Deserialize::deserialize(self)
254    }
255
256    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
257    where
258        T: de::DeserializeSeed<'de>,
259    {
260        seed.deserialize(self)
261    }
262
263    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Error>
264    where
265        V: de::Visitor<'de>,
266    {
267        de::Deserializer::deserialize_tuple(self, len, visitor)
268    }
269
270    fn struct_variant<V>(
271        self,
272        fields: &'static [&'static str],
273        visitor: V,
274    ) -> Result<V::Value, Error>
275    where
276        V: de::Visitor<'de>,
277    {
278        let name = "";
279        de::Deserializer::deserialize_struct(self, name, fields, visitor)
280    }
281}
282
283struct MapAndSeqAccess<'a, I>
284where
285    I: 'a + IntoIterator<Item = Result<Event, Error>>,
286{
287    de: &'a mut Deserializer<I>,
288    is_struct: bool,
289    remaining: Option<usize>,
290}
291
292impl<'a, I> MapAndSeqAccess<'a, I>
293where
294    I: 'a + IntoIterator<Item = Result<Event, Error>>,
295{
296    fn new(
297        de: &'a mut Deserializer<I>,
298        is_struct: bool,
299        len: Option<usize>,
300    ) -> MapAndSeqAccess<'a, I> {
301        MapAndSeqAccess {
302            de,
303            is_struct,
304            remaining: len,
305        }
306    }
307}
308
309impl<'de, 'a, I> de::SeqAccess<'de> for MapAndSeqAccess<'a, I>
310where
311    I: 'a + IntoIterator<Item = Result<Event, Error>>,
312{
313    type Error = Error;
314
315    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
316    where
317        T: de::DeserializeSeed<'de>,
318    {
319        if let Some(&Ok(Event::EndCollection)) = self.de.events.peek() {
320            return Ok(None);
321        }
322
323        self.remaining = self.remaining.map(|r| r.saturating_sub(1));
324        self.de
325            .with_option_mode(OptionMode::default(), |this| seed.deserialize(this))
326            .map(Some)
327    }
328
329    fn size_hint(&self) -> Option<usize> {
330        self.remaining
331    }
332}
333
334impl<'de, 'a, I> de::MapAccess<'de> for MapAndSeqAccess<'a, I>
335where
336    I: 'a + IntoIterator<Item = Result<Event, Error>>,
337{
338    type Error = Error;
339
340    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
341    where
342        K: de::DeserializeSeed<'de>,
343    {
344        if let Some(&Ok(Event::EndCollection)) = self.de.events.peek() {
345            return Ok(None);
346        }
347
348        self.remaining = self.remaining.map(|r| r.saturating_sub(1));
349        self.de
350            .with_option_mode(OptionMode::default(), |this| seed.deserialize(this))
351            .map(Some)
352    }
353
354    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
355    where
356        V: de::DeserializeSeed<'de>,
357    {
358        let option_mode = if self.is_struct {
359            OptionMode::StructField
360        } else {
361            OptionMode::default()
362        };
363        self.de
364            .with_option_mode(option_mode, |this| Ok(seed.deserialize(this)?))
365    }
366
367    fn size_hint(&self) -> Option<usize> {
368        self.remaining
369    }
370}
371
372/// Deserializes an instance of type `T` from a byte slice.
373pub fn from_bytes<T: de::DeserializeOwned>(bytes: &[u8]) -> Result<T, Error> {
374    let cursor = Cursor::new(bytes);
375    from_reader(cursor)
376}
377
378/// Deserializes an instance of type `T` from a plist file of any encoding.
379pub fn from_file<P: AsRef<Path>, T: de::DeserializeOwned>(path: P) -> Result<T, Error> {
380    let file = File::open(path).map_err(error::from_io_without_position)?;
381    from_reader(BufReader::new(file))
382}
383
384/// Deserializes an instance of type `T` from a seekable byte stream containing a plist of any encoding.
385pub fn from_reader<R: Read + Seek, T: de::DeserializeOwned>(reader: R) -> Result<T, Error> {
386    let reader = stream::Reader::new(reader);
387    let mut de = Deserializer::new(reader);
388    de::Deserialize::deserialize(&mut de)
389}
390
391/// Deserializes an instance of type `T` from a byte stream containing an XML encoded plist.
392pub fn from_reader_xml<R: Read, T: de::DeserializeOwned>(reader: R) -> Result<T, Error> {
393    let reader = stream::XmlReader::new(reader);
394    let mut de = Deserializer::new(reader);
395    de::Deserialize::deserialize(&mut de)
396}