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