serde_xml_rs/ser/
mod.rs

1use std::fmt::Display;
2use std::io::Write;
3
4use serde::ser::{self, Impossible, Serialize};
5
6use self::var::{Map, Struct};
7use crate::error::{Error, Result};
8
9mod var;
10
11/// A convenience method for serializing some object to a buffer.
12///
13/// # Examples
14///
15/// ```rust
16/// # #[macro_use]
17/// # extern crate serde_derive;
18/// # extern crate serde;
19/// # extern crate serde_xml_rs;
20/// # use serde_xml_rs::to_writer;
21/// #[derive(Serialize)]
22/// struct Person {
23///   name: String,
24///   age: u32,
25/// }
26///
27/// # fn main() {
28/// let mut buffer = Vec::new();
29/// let joe = Person {name: "Joe".to_string(), age: 42};
30///
31/// to_writer(&mut buffer, &joe).unwrap();
32///
33/// let serialized = String::from_utf8(buffer).unwrap();
34/// println!("{}", serialized);
35/// # }
36/// ```
37pub fn to_writer<W: Write, S: Serialize>(writer: W, value: &S) -> Result<()> {
38    let mut ser = Serializer::new(writer);
39    value.serialize(&mut ser)
40}
41
42/// A convenience method for serializing some object to a string.
43///
44/// # Examples
45///
46/// ```rust
47/// # #[macro_use]
48/// # extern crate serde_derive;
49/// # extern crate serde;
50/// # extern crate serde_xml_rs;
51/// # use serde_xml_rs::to_string;
52/// #[derive(Serialize)]
53/// struct Person {
54///   name: String,
55///   age: u32,
56/// }
57///
58/// # fn main() {
59///
60/// let joe = Person {name: "Joe".to_string(), age: 42};
61/// let serialized = to_string(&joe).unwrap();
62/// println!("{}", serialized);
63/// # }
64/// ```
65pub fn to_string<S: Serialize>(value: &S) -> Result<String> {
66    // Create a buffer and serialize our nodes into it
67    let mut writer = Vec::with_capacity(128);
68    to_writer(&mut writer, value)?;
69
70    // We then check that the serialized string is the same as what we expect
71    let string = String::from_utf8(writer)?;
72    Ok(string)
73}
74
75/// An XML `Serializer`.
76pub struct Serializer<W>
77where
78    W: Write,
79{
80    writer: W,
81}
82
83impl<W> Serializer<W>
84where
85    W: Write,
86{
87    pub fn new(writer: W) -> Self {
88        Self { writer: writer }
89    }
90
91    fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<()> {
92        write!(self.writer, "{}", primitive)?;
93        Ok(())
94    }
95
96    fn write_wrapped<S: Serialize>(&mut self, tag: &str, value: S) -> Result<()> {
97        write!(self.writer, "<{}>", tag)?;
98        value.serialize(&mut *self)?;
99        write!(self.writer, "</{}>", tag)?;
100        Ok(())
101    }
102}
103
104#[allow(unused_variables)]
105impl<'w, W> ser::Serializer for &'w mut Serializer<W>
106where
107    W: Write,
108{
109    type Ok = ();
110    type Error = Error;
111
112    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
113    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
114    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
115    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
116    type SerializeMap = Map<'w, W>;
117    type SerializeStruct = Struct<'w, W>;
118    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
119
120    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
121        if v {
122            write!(self.writer, "true")?;
123        } else {
124            write!(self.writer, "false")?;
125        }
126
127        Ok(())
128    }
129
130    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
131        self.write_primitive(v)
132    }
133
134    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
135        self.write_primitive(v)
136    }
137
138    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
139        self.write_primitive(v)
140    }
141
142    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
143        self.write_primitive(v)
144    }
145
146    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
147        self.write_primitive(v)
148    }
149
150    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
151        self.write_primitive(v)
152    }
153
154    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
155        self.write_primitive(v)
156    }
157
158    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
159        self.write_primitive(v)
160    }
161
162    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
163        self.write_primitive(v)
164    }
165
166    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
167        self.write_primitive(v)
168    }
169
170    fn serialize_char(self, v: char) -> Result<Self::Ok> {
171        self.write_primitive(v)
172    }
173
174    fn serialize_str(self, value: &str) -> Result<Self::Ok> {
175        self.write_primitive(value)
176    }
177
178    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
179        // TODO: I imagine you'd want to use base64 here.
180        // Not sure how to roundtrip effectively though...
181        Err(Error::UnsupportedOperation {
182            operation: "serialize_bytes".to_string(),
183        })
184    }
185
186    fn serialize_none(self) -> Result<Self::Ok> {
187        Ok(())
188    }
189
190    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok> {
191        value.serialize(self)
192    }
193
194    fn serialize_unit(self) -> Result<Self::Ok> {
195        self.serialize_none()
196    }
197
198    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
199        self.write_wrapped(name, ())
200    }
201
202    fn serialize_unit_variant(
203        self,
204        name: &'static str,
205        variant_index: u32,
206        variant: &'static str,
207    ) -> Result<Self::Ok> {
208        Err(Error::UnsupportedOperation {
209            operation: "serialize_unit_variant".to_string(),
210        })
211    }
212
213    fn serialize_newtype_struct<T: ?Sized + Serialize>(
214        self,
215        name: &'static str,
216        value: &T,
217    ) -> Result<Self::Ok> {
218        Err(Error::UnsupportedOperation {
219            operation: "serialize_newtype_struct".to_string(),
220        })
221    }
222
223    fn serialize_newtype_variant<T: ?Sized + Serialize>(
224        self,
225        name: &'static str,
226        variant_index: u32,
227        variant: &'static str,
228        value: &T,
229    ) -> Result<Self::Ok> {
230        self.write_wrapped(variant, value)
231    }
232
233    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
234        // TODO: Figure out how to constrain the things written to only be composites
235        Err(Error::UnsupportedOperation {
236            operation: "serialize_seq".to_string(),
237        })
238    }
239
240    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
241        Err(Error::UnsupportedOperation {
242            operation: "serialize_tuple".to_string(),
243        })
244    }
245
246    fn serialize_tuple_struct(
247        self,
248        name: &'static str,
249        len: usize,
250    ) -> Result<Self::SerializeTupleStruct> {
251        Err(Error::UnsupportedOperation {
252            operation: "serialize_tuple_struct".to_string(),
253        })
254    }
255
256    fn serialize_tuple_variant(
257        self,
258        name: &'static str,
259        variant_index: u32,
260        variant: &'static str,
261        len: usize,
262    ) -> Result<Self::SerializeTupleVariant> {
263        Err(Error::UnsupportedOperation {
264            operation: "serialize_tuple_variant".to_string(),
265        })
266    }
267
268    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
269        Ok(Map::new(self))
270    }
271
272    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
273        write!(self.writer, "<{}>", name)?;
274        Ok(Struct::new(self, name))
275    }
276
277    fn serialize_struct_variant(
278        self,
279        name: &'static str,
280        variant_index: u32,
281        variant: &'static str,
282        len: usize,
283    ) -> Result<Self::SerializeStructVariant> {
284        Err(Error::UnsupportedOperation {
285            operation: "Result".to_string(),
286        })
287    }
288}
289
290#[cfg(test)]
291mod tests {
292    use super::*;
293    use serde::ser::{SerializeMap, SerializeStruct};
294    use serde::Serializer as SerSerializer;
295    use serde_derive::Serialize;
296
297    #[test]
298    fn test_serialize_bool() {
299        let inputs = vec![(true, "true"), (false, "false")];
300
301        for (src, should_be) in inputs {
302            let mut buffer = Vec::new();
303
304            {
305                let mut ser = Serializer::new(&mut buffer);
306                ser.serialize_bool(src).unwrap();
307            }
308
309            let got = String::from_utf8(buffer).unwrap();
310            assert_eq!(got, should_be);
311        }
312    }
313
314    #[test]
315    fn test_start_serialize_struct() {
316        let mut buffer = Vec::new();
317
318        {
319            let mut ser = Serializer::new(&mut buffer);
320            let _ = ser.serialize_struct("foo", 0).unwrap();
321        }
322
323        let got = String::from_utf8(buffer).unwrap();
324        assert_eq!(got, "<foo>");
325    }
326
327    #[test]
328    fn test_serialize_struct_field() {
329        let mut buffer = Vec::new();
330
331        {
332            let mut ser = Serializer::new(&mut buffer);
333            let mut struct_ser = Struct::new(&mut ser, "baz");
334            struct_ser.serialize_field("foo", "bar").unwrap();
335        }
336
337        let got = String::from_utf8(buffer).unwrap();
338        assert_eq!(got, "<foo>bar</foo>");
339    }
340
341    #[test]
342    fn test_serialize_struct() {
343        #[derive(Serialize)]
344        struct Person {
345            name: String,
346            age: u32,
347        }
348
349        let bob = Person {
350            name: "Bob".to_string(),
351            age: 42,
352        };
353        let should_be = "<Person><name>Bob</name><age>42</age></Person>";
354        let mut buffer = Vec::new();
355
356        {
357            let mut ser = Serializer::new(&mut buffer);
358            bob.serialize(&mut ser).unwrap();
359        }
360
361        let got = String::from_utf8(buffer).unwrap();
362        assert_eq!(got, should_be);
363    }
364
365    #[test]
366    fn test_serialize_map_entries() {
367        let should_be = "<name>Bob</name><age>5</age>";
368        let mut buffer = Vec::new();
369
370        {
371            let mut ser = Serializer::new(&mut buffer);
372            let mut map = Map::new(&mut ser);
373            map.serialize_entry("name", "Bob").unwrap();
374            map.serialize_entry("age", "5").unwrap();
375        }
376
377        let got = String::from_utf8(buffer).unwrap();
378        assert_eq!(got, should_be);
379    }
380
381    #[test]
382    fn test_serialize_enum() {
383        #[derive(Serialize)]
384        #[allow(dead_code)]
385        enum Node {
386            Boolean(bool),
387            Number(f64),
388            String(String),
389        }
390
391        let mut buffer = Vec::new();
392        let should_be = "<Boolean>true</Boolean>";
393
394        {
395            let mut ser = Serializer::new(&mut buffer);
396            let node = Node::Boolean(true);
397            node.serialize(&mut ser).unwrap();
398        }
399
400        let got = String::from_utf8(buffer).unwrap();
401        assert_eq!(got, should_be);
402    }
403
404    #[test]
405    #[ignore]
406    fn serialize_a_list() {
407        let inputs = vec![1, 2, 3, 4];
408
409        let mut buffer = Vec::new();
410
411        {
412            let mut ser = Serializer::new(&mut buffer);
413            inputs.serialize(&mut ser).unwrap();
414        }
415
416        let got = String::from_utf8(buffer).unwrap();
417        println!("{}", got);
418        panic!();
419    }
420}