serde_xml_rs/ser/
mod.rs

1mod map;
2mod plain;
3mod seq;
4mod tuple;
5
6use self::{
7    map::{MapSerializer, StructSerializer},
8    seq::SeqSeralizer,
9    tuple::TupleSerializer,
10};
11use crate::error::{Error, Result};
12use log::debug;
13use serde::ser::Serialize;
14use std::{collections::HashMap, io::Write};
15use xml::writer::{EmitterConfig, EventWriter, XmlEvent};
16
17/// A convenience method for serializing some object to a buffer.
18///
19/// # Examples
20///
21/// ```rust
22/// # use serde::Serialize;
23/// # use serde_xml_rs::to_writer;
24/// #[derive(Serialize)]
25/// struct Person {
26///   name: String,
27///   age: u32,
28/// }
29///
30/// # fn main() {
31/// let mut buffer = Vec::new();
32/// let joe = Person {name: "Joe".to_string(), age: 42};
33///
34/// to_writer(&mut buffer, &joe).unwrap();
35///
36/// let serialized = String::from_utf8(buffer).unwrap();
37/// println!("{}", serialized);
38/// # }
39/// ```
40pub fn to_writer<W: Write, S: Serialize>(writer: W, value: &S) -> Result<()> {
41    let mut ser = Serializer::new(writer);
42    value.serialize(&mut ser)
43}
44
45/// A convenience method for serializing some object to a string.
46///
47/// # Examples
48///
49/// ```rust
50/// # use serde::Serialize;
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: EventWriter<W>,
81    root: bool,
82    current_tag: String,
83    current_tag_attrs: Option<HashMap<&'static str, String>>,
84}
85
86impl<W> Serializer<W>
87where
88    W: Write,
89{
90    fn new_from_writer(writer: EventWriter<W>) -> Self {
91        Self {
92            writer,
93            root: true,
94            current_tag: "".into(),
95            current_tag_attrs: None,
96        }
97    }
98
99    pub fn new(writer: W) -> Self {
100        Self::new_from_writer(EmitterConfig::new().create_writer(writer))
101    }
102
103    fn next(&mut self, event: XmlEvent) -> Result<()> {
104        self.writer.write(event)?;
105        Ok(())
106    }
107
108    fn characters(&mut self, s: &str) -> Result<()> {
109        self.next(XmlEvent::characters(s))
110    }
111
112    fn start_document(&mut self) -> Result<()> {
113        self.next(XmlEvent::StartDocument {
114            encoding: Default::default(),
115            standalone: Default::default(),
116            version: xml::common::XmlVersion::Version10,
117        })
118    }
119
120    fn open_root_tag(&mut self, name: &'static str) -> Result<()> {
121        if self.root {
122            self.root = false;
123            self.start_document()?;
124            self.open_tag(name)?;
125        }
126        Ok(())
127    }
128
129    fn open_tag(&mut self, tag_name: &str) -> Result<()> {
130        self.current_tag = tag_name.into();
131        self.current_tag_attrs = Some(HashMap::new());
132        Ok(())
133    }
134
135    fn reopen_tag(&mut self) -> Result<()> {
136        self.current_tag_attrs = Some(HashMap::new());
137        Ok(())
138    }
139
140    fn abandon_tag(&mut self) -> Result<()> {
141        self.current_tag = "".into();
142        self.current_tag_attrs = None;
143        Ok(())
144    }
145
146    fn add_attr(&mut self, name: &'static str, value: String) -> Result<()> {
147        self.current_tag_attrs
148            .as_mut()
149            .ok_or(Error::Custom {
150                field: format!("Cannot add attribute {}", name),
151            })
152            .map(|attrs| {
153                attrs.insert(name, value);
154            })
155    }
156
157    fn build_start_tag(&mut self) -> Result<bool> {
158        if let Some(attrs) = self.current_tag_attrs.take() {
159            self.start_tag(&self.current_tag(), attrs)?;
160            Ok(true)
161        } else {
162            Ok(false)
163        }
164    }
165
166    fn start_tag(&mut self, tag_name: &str, attrs: HashMap<&str, String>) -> Result<()> {
167        let element = attrs
168            .iter()
169            .fold(XmlEvent::start_element(tag_name), |b, (&name, value)| {
170                b.attr(name, value)
171            });
172
173        self.next(element.into())
174    }
175
176    fn end_tag(&mut self) -> Result<()> {
177        self.next(XmlEvent::end_element().into())
178    }
179
180    fn current_tag(&self) -> String {
181        self.current_tag.clone()
182    }
183}
184
185impl<'ser, W: Write> serde::ser::Serializer for &'ser mut Serializer<W> {
186    type Ok = ();
187    type Error = Error;
188
189    type SerializeSeq = SeqSeralizer<'ser, W>;
190    type SerializeTuple = TupleSerializer<'ser, W>;
191    type SerializeTupleStruct = TupleSerializer<'ser, W>;
192    type SerializeTupleVariant = TupleSerializer<'ser, W>;
193    type SerializeMap = MapSerializer<'ser, W>;
194    type SerializeStruct = StructSerializer<'ser, W>;
195    type SerializeStructVariant = StructSerializer<'ser, W>;
196
197    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
198        self.serialize_str(&v.to_string())
199    }
200
201    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
202        self.serialize_i64(i64::from(v))
203    }
204
205    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
206        self.serialize_i64(i64::from(v))
207    }
208
209    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
210        self.serialize_i64(i64::from(v))
211    }
212
213    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
214        self.serialize_str(&v.to_string())
215    }
216
217    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
218        self.serialize_u64(u64::from(v))
219    }
220
221    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
222        self.serialize_u64(u64::from(v))
223    }
224
225    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
226        self.serialize_u64(u64::from(v))
227    }
228
229    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
230        let must_close_tag = self.build_start_tag()?;
231        self.characters(&v.to_string())?;
232        if must_close_tag {
233            self.end_tag()?;
234        }
235        Ok(())
236    }
237
238    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
239        self.serialize_f64(f64::from(v))
240    }
241
242    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
243        self.serialize_str(&v.to_string())
244    }
245
246    fn serialize_char(self, v: char) -> Result<Self::Ok> {
247        self.serialize_str(&v.to_string())
248    }
249
250    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
251        let must_close_tag = self.build_start_tag()?;
252        self.characters(v)?;
253        if must_close_tag {
254            self.end_tag()?;
255        }
256        Ok(())
257    }
258
259    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
260        unimplemented!()
261    }
262
263    fn serialize_none(self) -> Result<Self::Ok> {
264        debug!("None");
265        let must_close_tag = self.build_start_tag()?;
266        if must_close_tag {
267            self.end_tag()?;
268        }
269        Ok(())
270    }
271
272    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
273    where
274        T: Serialize,
275    {
276        debug!("Some");
277        value.serialize(self)
278    }
279
280    fn serialize_unit(self) -> Result<Self::Ok> {
281        debug!("Unit");
282        let must_close_tag = self.build_start_tag()?;
283        if must_close_tag {
284            self.end_tag()?;
285        }
286        Ok(())
287    }
288
289    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
290        debug!("Unit struct {}", name);
291        self.serialize_unit()
292    }
293
294    fn serialize_unit_variant(
295        self,
296        name: &'static str,
297        _variant_index: u32,
298        variant: &'static str,
299    ) -> Result<Self::Ok> {
300        debug!("Unit variant {}::{}", name, variant);
301        self.start_tag(variant, HashMap::new())?;
302        self.serialize_unit()?;
303        self.end_tag()?;
304        Ok(())
305    }
306
307    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
308    where
309        T: Serialize,
310    {
311        debug!("Newtype struct {}", name);
312        value.serialize(self)
313    }
314
315    fn serialize_newtype_variant<T: ?Sized>(
316        self,
317        name: &'static str,
318        _variant_index: u32,
319        variant: &'static str,
320        value: &T,
321    ) -> Result<Self::Ok>
322    where
323        T: Serialize,
324    {
325        let must_close_tag = self.build_start_tag()?;
326
327        debug!("Newtype variant {}::{}", name, variant);
328        self.open_tag(variant)?;
329        value.serialize(&mut *self)?;
330
331        if must_close_tag {
332            self.end_tag()?;
333        }
334        Ok(())
335    }
336
337    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
338        debug!("Sequence");
339        Ok(SeqSeralizer::new(self))
340    }
341
342    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
343        debug!("Tuple");
344        let must_close_tag = self.build_start_tag()?;
345        Ok(TupleSerializer::new(self, must_close_tag))
346    }
347
348    fn serialize_tuple_struct(
349        self,
350        name: &'static str,
351        _len: usize,
352    ) -> Result<Self::SerializeTupleStruct> {
353        debug!("Tuple struct {}", name);
354        let must_close_tag = self.build_start_tag()?;
355        Ok(TupleSerializer::new(self, must_close_tag))
356    }
357
358    fn serialize_tuple_variant(
359        self,
360        name: &'static str,
361        _variant_index: u32,
362        variant: &'static str,
363        _len: usize,
364    ) -> Result<Self::SerializeTupleVariant> {
365        debug!("Tuple variant {}::{}", name, variant);
366        let must_close_tag = self.build_start_tag()?;
367        self.start_tag(variant, HashMap::new())?;
368        Ok(TupleSerializer::new(self, must_close_tag))
369    }
370
371    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
372        let must_close_tag = self.build_start_tag()?;
373        Ok(MapSerializer::new(self, must_close_tag))
374    }
375
376    fn serialize_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
377        self.open_root_tag(name)?;
378
379        debug!("Struct {}", name);
380        Ok(StructSerializer::new(self, false))
381    }
382
383    fn serialize_struct_variant(
384        self,
385        name: &'static str,
386        _variant_index: u32,
387        variant: &'static str,
388        _len: usize,
389    ) -> Result<Self::SerializeStructVariant> {
390        self.open_root_tag(name)?;
391
392        debug!("Struct variant {}", variant);
393        let must_close_tag = self.build_start_tag()?;
394        self.open_tag(variant)?;
395        Ok(StructSerializer::new(self, must_close_tag))
396    }
397}
398
399#[cfg(test)]
400mod tests {
401    use super::*;
402    use serde::Serialize;
403
404    #[test]
405    fn test_serialize_struct() {
406        #[derive(Serialize)]
407        struct Person {
408            name: String,
409            age: u32,
410        }
411
412        let bob = Person {
413            name: "Bob".to_string(),
414            age: 42,
415        };
416        let should_be = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Person><name>Bob</name><age>42</age></Person>";
417        let mut buffer = Vec::new();
418
419        {
420            let mut ser = Serializer::new(&mut buffer);
421            bob.serialize(&mut ser).unwrap();
422        }
423
424        let got = String::from_utf8(buffer).unwrap();
425        assert_eq!(got, should_be);
426    }
427
428    #[test]
429    fn test_serialize_enum() {
430        #[derive(Serialize)]
431        #[allow(dead_code)]
432        enum Node {
433            Boolean(bool),
434            Number(f64),
435            String(String),
436        }
437
438        let mut buffer = Vec::new();
439        let should_be = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Boolean>true</Boolean>";
440
441        {
442            let mut ser = Serializer::new(&mut buffer);
443            let node = Node::Boolean(true);
444            node.serialize(&mut ser).unwrap();
445        }
446
447        let got = String::from_utf8(buffer).unwrap();
448        assert_eq!(got, should_be);
449    }
450}