plist/
data.rs

1use std::fmt;
2
3use base64::{engine::general_purpose::STANDARD as BASE64_STANDARD, Engine};
4
5use crate::stream::xml_encode_data_base64;
6
7/// A byte buffer used for serialization to and from the plist data type.
8///
9/// You use it in types with derived `Serialize`/`Deserialize` traits.
10///
11/// ## Examples
12///
13/// ```rust
14/// extern crate plist;
15/// #[macro_use]
16/// extern crate serde_derive;
17///
18/// # fn main() {
19/// #[derive(Deserialize, Serialize)]
20/// struct Info {
21///     blob: plist::Data,
22/// }
23///
24/// let actual = Info { blob: plist::Data::new(vec![1, 2, 3, 4]) };
25///
26/// let mut xml_byte_buffer: Vec<u8> = vec![];
27/// plist::to_writer_xml(&mut xml_byte_buffer, &actual)
28///     .expect("serialize into xml");
29///
30/// let expected: Info = plist::from_reader_xml(xml_byte_buffer.as_slice())
31///     .expect("deserialize from xml");
32///
33/// assert_eq!(actual.blob, expected.blob);
34/// # }
35/// ```
36#[derive(Clone, PartialEq, Eq)]
37pub struct Data {
38    inner: Vec<u8>,
39}
40
41/// An error indicating a string was not valid XML data.
42#[derive(Debug)]
43pub struct InvalidXmlData(base64::DecodeError);
44
45impl Data {
46    /// Creates a new `Data` from vec of bytes.
47    pub fn new(bytes: Vec<u8>) -> Self {
48        Data { inner: bytes }
49    }
50
51    /// Create a `Data` object from an XML plist (Base-64) encoded string.
52    pub fn from_xml_format(b64_str: &str) -> Result<Self, InvalidXmlData> {
53        BASE64_STANDARD
54            .decode(b64_str)
55            .map_err(InvalidXmlData)
56            .map(Data::new)
57    }
58
59    /// Converts the `Data` to an XML plist (Base-64) string.
60    pub fn to_xml_format(&self) -> String {
61        xml_encode_data_base64(&self.inner)
62    }
63}
64
65impl From<Vec<u8>> for Data {
66    fn from(from: Vec<u8>) -> Self {
67        Data { inner: from }
68    }
69}
70
71impl From<Data> for Vec<u8> {
72    fn from(from: Data) -> Self {
73        from.inner
74    }
75}
76
77impl AsRef<[u8]> for Data {
78    fn as_ref(&self) -> &[u8] {
79        self.inner.as_ref()
80    }
81}
82
83impl AsMut<[u8]> for Data {
84    fn as_mut(&mut self) -> &mut [u8] {
85        self.inner.as_mut()
86    }
87}
88
89impl fmt::Debug for Data {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        self.inner.fmt(f)
92    }
93}
94
95impl fmt::Display for InvalidXmlData {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        write!(f, "Invalid XML data: '{}'", self.0)
98    }
99}
100
101impl std::error::Error for InvalidXmlData {}
102
103pub mod serde_impls {
104    use serde::{de, ser};
105    use std::fmt;
106
107    use crate::Data;
108
109    impl ser::Serialize for Data {
110        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
111        where
112            S: ser::Serializer,
113        {
114            serializer.serialize_bytes(self.as_ref())
115        }
116    }
117
118    struct DataVisitor;
119
120    impl<'de> de::Visitor<'de> for DataVisitor {
121        type Value = Data;
122
123        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
124            formatter.write_str("a byte array")
125        }
126
127        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
128        where
129            E: de::Error,
130        {
131            self.visit_byte_buf(v.to_owned())
132        }
133
134        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
135        where
136            E: de::Error,
137        {
138            Ok(v.into())
139        }
140    }
141
142    impl<'de> de::Deserialize<'de> for Data {
143        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144        where
145            D: de::Deserializer<'de>,
146        {
147            deserializer.deserialize_byte_buf(DataVisitor)
148        }
149    }
150}