plist/
de.rs

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