1 | //! Module to handle custom serde `Serializer`
|
2 |
|
3 | /// Implements writing primitives to the underlying writer.
|
4 | /// Implementor must provide `write_str(self, &str) -> Result<(), DeError>` method
|
5 | macro_rules! write_primitive {
|
6 | ($method:ident ( $ty:ty )) => {
|
7 | fn $method(mut self, value: $ty) -> Result<Self::Ok, Self::Error> {
|
8 | self.write_str(&value.to_string())?;
|
9 | Ok(self.writer)
|
10 | }
|
11 | };
|
12 | () => {
|
13 | fn serialize_bool(mut self, value: bool) -> Result<Self::Ok, Self::Error> {
|
14 | self.write_str(if value { "true" } else { "false" })?;
|
15 | Ok(self.writer)
|
16 | }
|
17 |
|
18 | write_primitive!(serialize_i8(i8));
|
19 | write_primitive!(serialize_i16(i16));
|
20 | write_primitive!(serialize_i32(i32));
|
21 | write_primitive!(serialize_i64(i64));
|
22 |
|
23 | write_primitive!(serialize_u8(u8));
|
24 | write_primitive!(serialize_u16(u16));
|
25 | write_primitive!(serialize_u32(u32));
|
26 | write_primitive!(serialize_u64(u64));
|
27 |
|
28 | serde_if_integer128! {
|
29 | write_primitive!(serialize_i128(i128));
|
30 | write_primitive!(serialize_u128(u128));
|
31 | }
|
32 |
|
33 | write_primitive!(serialize_f32(f32));
|
34 | write_primitive!(serialize_f64(f64));
|
35 |
|
36 | fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
|
37 | self.serialize_str(&value.to_string())
|
38 | }
|
39 |
|
40 | fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
|
41 | //TODO: customization point - allow user to decide how to encode bytes
|
42 | Err(DeError::Unsupported(
|
43 | "`serialize_bytes` not supported yet" .into(),
|
44 | ))
|
45 | }
|
46 |
|
47 | fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
48 | Ok(self.writer)
|
49 | }
|
50 |
|
51 | fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
|
52 | value.serialize(self)
|
53 | }
|
54 |
|
55 | fn serialize_unit_variant(
|
56 | self,
|
57 | _name: &'static str,
|
58 | _variant_index: u32,
|
59 | variant: &'static str,
|
60 | ) -> Result<Self::Ok, Self::Error> {
|
61 | self.serialize_str(variant)
|
62 | }
|
63 |
|
64 | fn serialize_newtype_struct<T: ?Sized + Serialize>(
|
65 | self,
|
66 | _name: &'static str,
|
67 | value: &T,
|
68 | ) -> Result<Self::Ok, Self::Error> {
|
69 | value.serialize(self)
|
70 | }
|
71 | };
|
72 | }
|
73 |
|
74 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
75 |
|
76 | mod content;
|
77 | mod element;
|
78 | pub(crate) mod key;
|
79 | pub(crate) mod simple_type;
|
80 |
|
81 | use self::content::ContentSerializer;
|
82 | use self::element::ElementSerializer;
|
83 | use crate::errors::serialize::DeError;
|
84 | use crate::writer::Indentation;
|
85 | use serde::ser::{self, Serialize};
|
86 | use serde::serde_if_integer128;
|
87 | use std::fmt::Write;
|
88 | use std::str::from_utf8;
|
89 |
|
90 | /// Serialize struct into a `Write`r.
|
91 | ///
|
92 | /// # Examples
|
93 | ///
|
94 | /// ```
|
95 | /// # use quick_xml::se::to_writer;
|
96 | /// # use serde::Serialize;
|
97 | /// # use pretty_assertions::assert_eq;
|
98 | /// #[derive(Serialize)]
|
99 | /// struct Root<'a> {
|
100 | /// #[serde(rename = "@attribute" )]
|
101 | /// attribute: &'a str,
|
102 | /// element: &'a str,
|
103 | /// #[serde(rename = "$text" )]
|
104 | /// text: &'a str,
|
105 | /// }
|
106 | ///
|
107 | /// let data = Root {
|
108 | /// attribute: "attribute content" ,
|
109 | /// element: "element content" ,
|
110 | /// text: "text content" ,
|
111 | /// };
|
112 | ///
|
113 | /// let mut buffer = String::new();
|
114 | /// to_writer(&mut buffer, &data).unwrap();
|
115 | /// assert_eq!(
|
116 | /// buffer,
|
117 | /// // The root tag name is automatically deduced from the struct name
|
118 | /// // This will not work for other types or struct with #[serde(flatten)] fields
|
119 | /// "<Root attribute= \"attribute content \"> \
|
120 | /// <element>element content</element> \
|
121 | /// text content \
|
122 | /// </Root>"
|
123 | /// );
|
124 | /// ```
|
125 | pub fn to_writer<W, T>(mut writer: W, value: &T) -> Result<(), DeError>
|
126 | where
|
127 | W: Write,
|
128 | T: ?Sized + Serialize,
|
129 | {
|
130 | value.serialize(Serializer::new(&mut writer))
|
131 | }
|
132 |
|
133 | /// Serialize struct into a `String`.
|
134 | ///
|
135 | /// # Examples
|
136 | ///
|
137 | /// ```
|
138 | /// # use quick_xml::se::to_string;
|
139 | /// # use serde::Serialize;
|
140 | /// # use pretty_assertions::assert_eq;
|
141 | /// #[derive(Serialize)]
|
142 | /// struct Root<'a> {
|
143 | /// #[serde(rename = "@attribute" )]
|
144 | /// attribute: &'a str,
|
145 | /// element: &'a str,
|
146 | /// #[serde(rename = "$text" )]
|
147 | /// text: &'a str,
|
148 | /// }
|
149 | ///
|
150 | /// let data = Root {
|
151 | /// attribute: "attribute content" ,
|
152 | /// element: "element content" ,
|
153 | /// text: "text content" ,
|
154 | /// };
|
155 | ///
|
156 | /// assert_eq!(
|
157 | /// to_string(&data).unwrap(),
|
158 | /// // The root tag name is automatically deduced from the struct name
|
159 | /// // This will not work for other types or struct with #[serde(flatten)] fields
|
160 | /// "<Root attribute= \"attribute content \"> \
|
161 | /// <element>element content</element> \
|
162 | /// text content \
|
163 | /// </Root>"
|
164 | /// );
|
165 | /// ```
|
166 | pub fn to_string<T>(value: &T) -> Result<String, DeError>
|
167 | where
|
168 | T: ?Sized + Serialize,
|
169 | {
|
170 | let mut buffer: String = String::new();
|
171 | to_writer(&mut buffer, value)?;
|
172 | Ok(buffer)
|
173 | }
|
174 |
|
175 | /// Serialize struct into a `Write`r using specified root tag name.
|
176 | /// `root_tag` should be valid [XML name], otherwise error is returned.
|
177 | ///
|
178 | /// # Examples
|
179 | ///
|
180 | /// ```
|
181 | /// # use quick_xml::se::to_writer_with_root;
|
182 | /// # use serde::Serialize;
|
183 | /// # use pretty_assertions::assert_eq;
|
184 | /// #[derive(Serialize)]
|
185 | /// struct Root<'a> {
|
186 | /// #[serde(rename = "@attribute" )]
|
187 | /// attribute: &'a str,
|
188 | /// element: &'a str,
|
189 | /// #[serde(rename = "$text" )]
|
190 | /// text: &'a str,
|
191 | /// }
|
192 | ///
|
193 | /// let data = Root {
|
194 | /// attribute: "attribute content" ,
|
195 | /// element: "element content" ,
|
196 | /// text: "text content" ,
|
197 | /// };
|
198 | ///
|
199 | /// let mut buffer = String::new();
|
200 | /// to_writer_with_root(&mut buffer, "top-level" , &data).unwrap();
|
201 | /// assert_eq!(
|
202 | /// buffer,
|
203 | /// "<top-level attribute= \"attribute content \"> \
|
204 | /// <element>element content</element> \
|
205 | /// text content \
|
206 | /// </top-level>"
|
207 | /// );
|
208 | /// ```
|
209 | ///
|
210 | /// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
|
211 | pub fn to_writer_with_root<W, T>(mut writer: W, root_tag: &str, value: &T) -> Result<(), DeError>
|
212 | where
|
213 | W: Write,
|
214 | T: ?Sized + Serialize,
|
215 | {
|
216 | value.serialize(Serializer::with_root(&mut writer, root_tag:Some(root_tag))?)
|
217 | }
|
218 |
|
219 | /// Serialize struct into a `String` using specified root tag name.
|
220 | /// `root_tag` should be valid [XML name], otherwise error is returned.
|
221 | ///
|
222 | /// # Examples
|
223 | ///
|
224 | /// ```
|
225 | /// # use quick_xml::se::to_string_with_root;
|
226 | /// # use serde::Serialize;
|
227 | /// # use pretty_assertions::assert_eq;
|
228 | /// #[derive(Serialize)]
|
229 | /// struct Root<'a> {
|
230 | /// #[serde(rename = "@attribute" )]
|
231 | /// attribute: &'a str,
|
232 | /// element: &'a str,
|
233 | /// #[serde(rename = "$text" )]
|
234 | /// text: &'a str,
|
235 | /// }
|
236 | ///
|
237 | /// let data = Root {
|
238 | /// attribute: "attribute content" ,
|
239 | /// element: "element content" ,
|
240 | /// text: "text content" ,
|
241 | /// };
|
242 | ///
|
243 | /// assert_eq!(
|
244 | /// to_string_with_root("top-level" , &data).unwrap(),
|
245 | /// "<top-level attribute= \"attribute content \"> \
|
246 | /// <element>element content</element> \
|
247 | /// text content \
|
248 | /// </top-level>"
|
249 | /// );
|
250 | /// ```
|
251 | ///
|
252 | /// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
|
253 | pub fn to_string_with_root<T>(root_tag: &str, value: &T) -> Result<String, DeError>
|
254 | where
|
255 | T: ?Sized + Serialize,
|
256 | {
|
257 | let mut buffer: String = String::new();
|
258 | to_writer_with_root(&mut buffer, root_tag, value)?;
|
259 | Ok(buffer)
|
260 | }
|
261 |
|
262 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
263 |
|
264 | /// Defines which characters would be escaped in [`Text`] events and attribute
|
265 | /// values.
|
266 | ///
|
267 | /// [`Text`]: crate::events::Event::Text
|
268 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
269 | pub enum QuoteLevel {
|
270 | /// Performs escaping, escape all characters that could have special meaning
|
271 | /// in the XML. This mode is compatible with SGML specification.
|
272 | ///
|
273 | /// Characters that will be replaced:
|
274 | ///
|
275 | /// Original | Replacement
|
276 | /// ---------|------------
|
277 | /// `<` | `<`
|
278 | /// `>` | `>`
|
279 | /// `&` | `&`
|
280 | /// `"` | `"`
|
281 | /// `'` | `'`
|
282 | Full,
|
283 | /// Performs escaping that is compatible with SGML specification.
|
284 | ///
|
285 | /// This level adds escaping of `>` to the `Minimal` level, which is [required]
|
286 | /// for compatibility with SGML.
|
287 | ///
|
288 | /// Characters that will be replaced:
|
289 | ///
|
290 | /// Original | Replacement
|
291 | /// ---------|------------
|
292 | /// `<` | `<`
|
293 | /// `>` | `>`
|
294 | /// `&` | `&`
|
295 | ///
|
296 | /// [required]: https://www.w3.org/TR/xml11/#syntax
|
297 | Partial,
|
298 | /// Performs the minimal possible escaping, escape only strictly necessary
|
299 | /// characters.
|
300 | ///
|
301 | /// Characters that will be replaced:
|
302 | ///
|
303 | /// Original | Replacement
|
304 | /// ---------|------------
|
305 | /// `<` | `<`
|
306 | /// `&` | `&`
|
307 | Minimal,
|
308 | }
|
309 |
|
310 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
311 |
|
312 | /// Implements serialization method by forwarding it to the serializer created by
|
313 | /// the helper method [`Serializer::ser`].
|
314 | macro_rules! forward {
|
315 | ($name:ident($ty:ty)) => {
|
316 | fn $name(self, value: $ty) -> Result<Self::Ok, Self::Error> {
|
317 | self.ser(&concat!("`" , stringify!($ty), "`" ))?.$name(value)
|
318 | }
|
319 | };
|
320 | }
|
321 |
|
322 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
323 |
|
324 | /// Almost all characters can form a name. Citation from <https://www.w3.org/TR/xml11/#sec-xml11>:
|
325 | ///
|
326 | /// > The overall philosophy of names has changed since XML 1.0. Whereas XML 1.0
|
327 | /// > provided a rigid definition of names, wherein everything that was not permitted
|
328 | /// > was forbidden, XML 1.1 names are designed so that everything that is not
|
329 | /// > forbidden (for a specific reason) is permitted. Since Unicode will continue
|
330 | /// > to grow past version 4.0, further changes to XML can be avoided by allowing
|
331 | /// > almost any character, including those not yet assigned, in names.
|
332 | ///
|
333 | /// <https://www.w3.org/TR/xml11/#NT-NameStartChar>
|
334 | const fn is_xml11_name_start_char(ch: char) -> bool {
|
335 | match ch {
|
336 | ':'
|
337 | | 'A' ..='Z'
|
338 | | '_'
|
339 | | 'a' ..='z'
|
340 | | ' \u{00C0}' ..=' \u{00D6}'
|
341 | | ' \u{00D8}' ..=' \u{00F6}'
|
342 | | ' \u{00F8}' ..=' \u{02FF}'
|
343 | | ' \u{0370}' ..=' \u{037D}'
|
344 | | ' \u{037F}' ..=' \u{1FFF}'
|
345 | | ' \u{200C}' ..=' \u{200D}'
|
346 | | ' \u{2070}' ..=' \u{218F}'
|
347 | | ' \u{2C00}' ..=' \u{2FEF}'
|
348 | | ' \u{3001}' ..=' \u{D7FF}'
|
349 | | ' \u{F900}' ..=' \u{FDCF}'
|
350 | | ' \u{FDF0}' ..=' \u{FFFD}'
|
351 | | ' \u{10000}' ..=' \u{EFFFF}' => true,
|
352 | _ => false,
|
353 | }
|
354 | }
|
355 | /// <https://www.w3.org/TR/xml11/#NT-NameChar>
|
356 | const fn is_xml11_name_char(ch: char) -> bool {
|
357 | match ch {
|
358 | '-' | '.' | '0' ..='9' | ' \u{00B7}' | ' \u{0300}' ..=' \u{036F}' | ' \u{203F}' ..=' \u{2040}' => {
|
359 | true
|
360 | }
|
361 | _ => is_xml11_name_start_char(ch),
|
362 | }
|
363 | }
|
364 |
|
365 | /// Helper struct to self-defense from errors
|
366 | #[derive (Clone, Copy, Debug, PartialEq)]
|
367 | pub(self) struct XmlName<'n>(&'n str);
|
368 |
|
369 | impl<'n> XmlName<'n> {
|
370 | /// Checks correctness of the XML name according to [XML 1.1 specification]
|
371 | ///
|
372 | /// [XML 1.1 specification]: https://www.w3.org/TR/xml11/#NT-Name
|
373 | pub fn try_from(name: &'n str) -> Result<XmlName<'n>, DeError> {
|
374 | //TODO: Customization point: allow user to decide if he want to reject or encode the name
|
375 | match name.chars().next() {
|
376 | Some(ch: char) if !is_xml11_name_start_char(ch) => Err(DeError::Unsupported(
|
377 | formatString!("character ` {ch}` is not allowed at the start of an XML name ` {name}`" )
|
378 | .into(),
|
379 | )),
|
380 | _ => match name.matches(|ch: char| !is_xml11_name_char(ch)).next() {
|
381 | Some(s: &str) => Err(DeError::Unsupported(
|
382 | format!("character ` {s}` is not allowed in an XML name ` {name}`" ).into(),
|
383 | )),
|
384 | None => Ok(XmlName(name)),
|
385 | },
|
386 | }
|
387 | }
|
388 | }
|
389 |
|
390 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
391 |
|
392 | pub(crate) enum Indent<'i> {
|
393 | None,
|
394 | Owned(Indentation),
|
395 | Borrow(&'i mut Indentation),
|
396 | }
|
397 |
|
398 | impl<'i> Indent<'i> {
|
399 | pub fn borrow(&mut self) -> Indent {
|
400 | match self {
|
401 | Self::None => Indent::None,
|
402 | Self::Owned(ref mut i) => Indent::Borrow(i),
|
403 | Self::Borrow(i) => Indent::Borrow(i),
|
404 | }
|
405 | }
|
406 |
|
407 | pub fn increase(&mut self) {
|
408 | match self {
|
409 | Self::None => {}
|
410 | Self::Owned(i) => i.grow(),
|
411 | Self::Borrow(i) => i.grow(),
|
412 | }
|
413 | }
|
414 |
|
415 | pub fn decrease(&mut self) {
|
416 | match self {
|
417 | Self::None => {}
|
418 | Self::Owned(i) => i.shrink(),
|
419 | Self::Borrow(i) => i.shrink(),
|
420 | }
|
421 | }
|
422 |
|
423 | pub fn write_indent<W: std::fmt::Write>(&mut self, mut writer: W) -> Result<(), DeError> {
|
424 | match self {
|
425 | Self::None => {}
|
426 | Self::Owned(i) => {
|
427 | writer.write_char(' \n' )?;
|
428 | writer.write_str(from_utf8(i.current())?)?;
|
429 | }
|
430 | Self::Borrow(i) => {
|
431 | writer.write_char(' \n' )?;
|
432 | writer.write_str(from_utf8(i.current())?)?;
|
433 | }
|
434 | }
|
435 | Ok(())
|
436 | }
|
437 | }
|
438 |
|
439 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
440 |
|
441 | /// A Serializer
|
442 | pub struct Serializer<'w, 'r, W: Write> {
|
443 | ser: ContentSerializer<'w, 'r, W>,
|
444 | /// Name of the root tag. If not specified, deduced from the structure name
|
445 | root_tag: Option<XmlName<'r>>,
|
446 | }
|
447 |
|
448 | impl<'w, 'r, W: Write> Serializer<'w, 'r, W> {
|
449 | /// Creates a new `Serializer` that uses struct name as a root tag name.
|
450 | ///
|
451 | /// Note, that attempt to serialize a non-struct (including unit structs
|
452 | /// and newtype structs) will end up to an error. Use `with_root` to create
|
453 | /// serializer with explicitly defined root element name
|
454 | pub fn new(writer: &'w mut W) -> Self {
|
455 | Self {
|
456 | ser: ContentSerializer {
|
457 | writer,
|
458 | level: QuoteLevel::Full,
|
459 | indent: Indent::None,
|
460 | write_indent: false,
|
461 | expand_empty_elements: false,
|
462 | },
|
463 | root_tag: None,
|
464 | }
|
465 | }
|
466 |
|
467 | /// Creates a new `Serializer` that uses specified root tag name. `name` should
|
468 | /// be valid [XML name], otherwise error is returned.
|
469 | ///
|
470 | /// # Examples
|
471 | ///
|
472 | /// When serializing a primitive type, only its representation will be written:
|
473 | ///
|
474 | /// ```
|
475 | /// # use pretty_assertions::assert_eq;
|
476 | /// # use serde::Serialize;
|
477 | /// # use quick_xml::se::Serializer;
|
478 | ///
|
479 | /// let mut buffer = String::new();
|
480 | /// let ser = Serializer::with_root(&mut buffer, Some("root" )).unwrap();
|
481 | ///
|
482 | /// "node" .serialize(ser).unwrap();
|
483 | /// assert_eq!(buffer, "<root>node</root>" );
|
484 | /// ```
|
485 | ///
|
486 | /// When serializing a struct, newtype struct, unit struct or tuple `root_tag`
|
487 | /// is used as tag name of root(s) element(s):
|
488 | ///
|
489 | /// ```
|
490 | /// # use pretty_assertions::assert_eq;
|
491 | /// # use serde::Serialize;
|
492 | /// # use quick_xml::se::Serializer;
|
493 | ///
|
494 | /// #[derive(Debug, PartialEq, Serialize)]
|
495 | /// struct Struct {
|
496 | /// question: String,
|
497 | /// answer: u32,
|
498 | /// }
|
499 | ///
|
500 | /// let mut buffer = String::new();
|
501 | /// let ser = Serializer::with_root(&mut buffer, Some("root" )).unwrap();
|
502 | ///
|
503 | /// let data = Struct {
|
504 | /// question: "The Ultimate Question of Life, the Universe, and Everything" .into(),
|
505 | /// answer: 42,
|
506 | /// };
|
507 | ///
|
508 | /// data.serialize(ser).unwrap();
|
509 | /// assert_eq!(
|
510 | /// buffer,
|
511 | /// "<root> \
|
512 | /// <question>The Ultimate Question of Life, the Universe, and Everything</question> \
|
513 | /// <answer>42</answer> \
|
514 | /// </root>"
|
515 | /// );
|
516 | /// ```
|
517 | ///
|
518 | /// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
|
519 | pub fn with_root(writer: &'w mut W, root_tag: Option<&'r str>) -> Result<Self, DeError> {
|
520 | Ok(Self {
|
521 | ser: ContentSerializer {
|
522 | writer,
|
523 | level: QuoteLevel::Full,
|
524 | indent: Indent::None,
|
525 | write_indent: false,
|
526 | expand_empty_elements: false,
|
527 | },
|
528 | root_tag: root_tag.map(|tag| XmlName::try_from(tag)).transpose()?,
|
529 | })
|
530 | }
|
531 |
|
532 | /// Enable or disable expansion of empty elements. Defaults to `false`.
|
533 | ///
|
534 | /// # Examples
|
535 | ///
|
536 | /// ```
|
537 | /// # use pretty_assertions::assert_eq;
|
538 | /// # use serde::Serialize;
|
539 | /// # use quick_xml::se::Serializer;
|
540 | ///
|
541 | /// #[derive(Debug, PartialEq, Serialize)]
|
542 | /// struct Struct {
|
543 | /// question: Option<String>,
|
544 | /// }
|
545 | ///
|
546 | /// let mut buffer = String::new();
|
547 | /// let mut ser = Serializer::new(&mut buffer);
|
548 | /// ser.expand_empty_elements(true);
|
549 | ///
|
550 | /// let data = Struct {
|
551 | /// question: None,
|
552 | /// };
|
553 | ///
|
554 | /// data.serialize(ser).unwrap();
|
555 | /// assert_eq!(
|
556 | /// buffer,
|
557 | /// "<Struct><question></question></Struct>"
|
558 | /// );
|
559 | /// ```
|
560 | pub fn expand_empty_elements(&mut self, expand: bool) -> &mut Self {
|
561 | self.ser.expand_empty_elements = expand;
|
562 | self
|
563 | }
|
564 |
|
565 | /// Configure indent for a serializer
|
566 | pub fn indent(&mut self, indent_char: char, indent_size: usize) -> &mut Self {
|
567 | self.ser.indent = Indent::Owned(Indentation::new(indent_char as u8, indent_size));
|
568 | self
|
569 | }
|
570 |
|
571 | /// Set the indent object for a serializer
|
572 | pub(crate) fn set_indent(&mut self, indent: Indent<'r>) -> &mut Self {
|
573 | self.ser.indent = indent;
|
574 | self
|
575 | }
|
576 |
|
577 | /// Creates actual serializer or returns an error if root tag is not defined.
|
578 | /// In that case `err` contains the name of type that cannot be serialized.
|
579 | fn ser(self, err: &str) -> Result<ElementSerializer<'w, 'r, W>, DeError> {
|
580 | if let Some(key) = self.root_tag {
|
581 | Ok(ElementSerializer { ser: self.ser, key })
|
582 | } else {
|
583 | Err(DeError::Unsupported(
|
584 | format!("cannot serialize {} without defined root tag" , err).into(),
|
585 | ))
|
586 | }
|
587 | }
|
588 |
|
589 | /// Creates actual serializer using root tag or a specified `key` if root tag
|
590 | /// is not defined. Returns an error if root tag is not defined and a `key`
|
591 | /// does not conform [XML rules](XmlName::try_from) for names.
|
592 | fn ser_name(self, key: &'static str) -> Result<ElementSerializer<'w, 'r, W>, DeError> {
|
593 | Ok(ElementSerializer {
|
594 | ser: self.ser,
|
595 | key: match self.root_tag {
|
596 | Some(key) => key,
|
597 | None => XmlName::try_from(key)?,
|
598 | },
|
599 | })
|
600 | }
|
601 | }
|
602 |
|
603 | impl<'w, 'r, W: Write> ser::Serializer for Serializer<'w, 'r, W> {
|
604 | type Ok = ();
|
605 | type Error = DeError;
|
606 |
|
607 | type SerializeSeq = <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeSeq;
|
608 | type SerializeTuple = <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeTuple;
|
609 | type SerializeTupleStruct =
|
610 | <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeTupleStruct;
|
611 | type SerializeTupleVariant =
|
612 | <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeTupleVariant;
|
613 | type SerializeMap = <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeMap;
|
614 | type SerializeStruct = <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeStruct;
|
615 | type SerializeStructVariant =
|
616 | <ElementSerializer<'w, 'r, W> as ser::Serializer>::SerializeStructVariant;
|
617 |
|
618 | forward!(serialize_bool(bool));
|
619 |
|
620 | forward!(serialize_i8(i8));
|
621 | forward!(serialize_i16(i16));
|
622 | forward!(serialize_i32(i32));
|
623 | forward!(serialize_i64(i64));
|
624 |
|
625 | forward!(serialize_u8(u8));
|
626 | forward!(serialize_u16(u16));
|
627 | forward!(serialize_u32(u32));
|
628 | forward!(serialize_u64(u64));
|
629 |
|
630 | serde_if_integer128! {
|
631 | forward!(serialize_i128(i128));
|
632 | forward!(serialize_u128(u128));
|
633 | }
|
634 |
|
635 | forward!(serialize_f32(f32));
|
636 | forward!(serialize_f64(f64));
|
637 |
|
638 | forward!(serialize_char(char));
|
639 | forward!(serialize_str(&str));
|
640 | forward!(serialize_bytes(&[u8]));
|
641 |
|
642 | fn serialize_none(self) -> Result<Self::Ok, DeError> {
|
643 | Ok(())
|
644 | }
|
645 |
|
646 | fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, DeError> {
|
647 | value.serialize(self)
|
648 | }
|
649 |
|
650 | fn serialize_unit(self) -> Result<Self::Ok, DeError> {
|
651 | self.ser("`()`" )?.serialize_unit()
|
652 | }
|
653 |
|
654 | fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, DeError> {
|
655 | self.ser_name(name)?.serialize_unit_struct(name)
|
656 | }
|
657 |
|
658 | fn serialize_unit_variant(
|
659 | self,
|
660 | name: &'static str,
|
661 | variant_index: u32,
|
662 | variant: &'static str,
|
663 | ) -> Result<Self::Ok, DeError> {
|
664 | self.ser_name(name)?
|
665 | .serialize_unit_variant(name, variant_index, variant)
|
666 | }
|
667 |
|
668 | fn serialize_newtype_struct<T: ?Sized + Serialize>(
|
669 | self,
|
670 | name: &'static str,
|
671 | value: &T,
|
672 | ) -> Result<Self::Ok, DeError> {
|
673 | self.ser_name(name)?.serialize_newtype_struct(name, value)
|
674 | }
|
675 |
|
676 | fn serialize_newtype_variant<T: ?Sized + Serialize>(
|
677 | self,
|
678 | name: &'static str,
|
679 | variant_index: u32,
|
680 | variant: &'static str,
|
681 | value: &T,
|
682 | ) -> Result<Self::Ok, DeError> {
|
683 | self.ser_name(name)?
|
684 | .serialize_newtype_variant(name, variant_index, variant, value)
|
685 | }
|
686 |
|
687 | fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, DeError> {
|
688 | self.ser("sequence" )?.serialize_seq(len)
|
689 | }
|
690 |
|
691 | fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, DeError> {
|
692 | self.ser("unnamed tuple" )?.serialize_tuple(len)
|
693 | }
|
694 |
|
695 | fn serialize_tuple_struct(
|
696 | self,
|
697 | name: &'static str,
|
698 | len: usize,
|
699 | ) -> Result<Self::SerializeTupleStruct, DeError> {
|
700 | self.ser_name(name)?.serialize_tuple_struct(name, len)
|
701 | }
|
702 |
|
703 | fn serialize_tuple_variant(
|
704 | self,
|
705 | name: &'static str,
|
706 | variant_index: u32,
|
707 | variant: &'static str,
|
708 | len: usize,
|
709 | ) -> Result<Self::SerializeTupleVariant, DeError> {
|
710 | self.ser_name(name)?
|
711 | .serialize_tuple_variant(name, variant_index, variant, len)
|
712 | }
|
713 |
|
714 | fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, DeError> {
|
715 | self.ser("map" )?.serialize_map(len)
|
716 | }
|
717 |
|
718 | fn serialize_struct(
|
719 | self,
|
720 | name: &'static str,
|
721 | len: usize,
|
722 | ) -> Result<Self::SerializeStruct, DeError> {
|
723 | self.ser_name(name)?.serialize_struct(name, len)
|
724 | }
|
725 |
|
726 | fn serialize_struct_variant(
|
727 | self,
|
728 | name: &'static str,
|
729 | variant_index: u32,
|
730 | variant: &'static str,
|
731 | len: usize,
|
732 | ) -> Result<Self::SerializeStructVariant, DeError> {
|
733 | self.ser_name(name)?
|
734 | .serialize_struct_variant(name, variant_index, variant, len)
|
735 | }
|
736 | }
|
737 | |