From f783f2dc5d214de8438b9e04e9c8719842ff57d2 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 18 Feb 2023 21:51:11 +0500 Subject: [PATCH] Add helper functions `to_*_with_root` that writes XML with the specified root tag name --- Changelog.md | 3 + src/se/mod.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 18a8d866..14287407 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,8 @@ - [#541]: Deserialize specially named `$text` enum variant in [externally tagged] enums from textual content +- [#556]: `to_writer` and `to_string` now accept `?Sized` types +- [#556]: Add new `to_writer_with_root` and `to_string_with_root` helper functions ### Bug Fixes @@ -29,6 +31,7 @@ [#510]: https://github.com/tafia/quick-xml/issues/510 [#537]: https://github.com/tafia/quick-xml/issues/537 [#541]: https://github.com/tafia/quick-xml/pull/541 +[#556]: https://github.com/tafia/quick-xml/pull/556 ## 0.27.1 -- 2022-12-28 diff --git a/src/se/mod.rs b/src/se/mod.rs index 8e559d35..4dc65015 100644 --- a/src/se/mod.rs +++ b/src/se/mod.rs @@ -87,16 +87,170 @@ use serde::serde_if_integer128; use std::fmt::Write; use std::str::from_utf8; -/// Serialize struct into a `Write`r -pub fn to_writer(writer: W, value: &S) -> Result { +/// Serialize struct into a `Write`r. +/// +/// # Examples +/// +/// ``` +/// # use quick_xml::se::to_writer; +/// # use serde::Serialize; +/// # use pretty_assertions::assert_eq; +/// #[derive(Serialize)] +/// struct Root<'a> { +/// #[serde(rename = "@attribute")] +/// attribute: &'a str, +/// element: &'a str, +/// #[serde(rename = "$text")] +/// text: &'a str, +/// } +/// +/// let data = Root { +/// attribute: "attribute content", +/// element: "element content", +/// text: "text content", +/// }; +/// +/// assert_eq!( +/// to_writer(String::new(), &data).unwrap(), +/// // The root tag name is automatically deduced from the struct name +/// // This will not work for other types or struct with #[serde(flatten)] fields +/// "\ +/// element content\ +/// text content\ +/// " +/// ); +/// ``` +pub fn to_writer(writer: W, value: &T) -> Result +where + W: Write, + T: ?Sized + Serialize, +{ value.serialize(Serializer::new(writer)) } -/// Serialize struct into a `String` -pub fn to_string(value: &S) -> Result { +/// Serialize struct into a `String`. +/// +/// # Examples +/// +/// ``` +/// # use quick_xml::se::to_string; +/// # use serde::Serialize; +/// # use pretty_assertions::assert_eq; +/// #[derive(Serialize)] +/// struct Root<'a> { +/// #[serde(rename = "@attribute")] +/// attribute: &'a str, +/// element: &'a str, +/// #[serde(rename = "$text")] +/// text: &'a str, +/// } +/// +/// let data = Root { +/// attribute: "attribute content", +/// element: "element content", +/// text: "text content", +/// }; +/// +/// assert_eq!( +/// to_string(&data).unwrap(), +/// // The root tag name is automatically deduced from the struct name +/// // This will not work for other types or struct with #[serde(flatten)] fields +/// "\ +/// element content\ +/// text content\ +/// " +/// ); +/// ``` +pub fn to_string(value: &T) -> Result +where + T: ?Sized + Serialize, +{ to_writer(String::new(), value) } +/// Serialize struct into a `Write`r using specified root tag name. +/// `root_tag` should be valid [XML name], otherwise error is returned. +/// +/// # Examples +/// +/// ``` +/// # use quick_xml::se::to_writer_with_root; +/// # use serde::Serialize; +/// # use pretty_assertions::assert_eq; +/// #[derive(Serialize)] +/// struct Root<'a> { +/// #[serde(rename = "@attribute")] +/// attribute: &'a str, +/// element: &'a str, +/// #[serde(rename = "$text")] +/// text: &'a str, +/// } +/// +/// let data = Root { +/// attribute: "attribute content", +/// element: "element content", +/// text: "text content", +/// }; +/// +/// assert_eq!( +/// to_writer_with_root(String::new(), "top-level", &data).unwrap(), +/// "\ +/// element content\ +/// text content\ +/// " +/// ); +/// ``` +/// +/// [XML name]: https://www.w3.org/TR/REC-xml/#NT-Name +pub fn to_writer_with_root(writer: W, root_tag: &str, value: &T) -> Result +where + W: Write, + T: ?Sized + Serialize, +{ + value.serialize(Serializer::with_root(writer, Some(root_tag))?) +} + +/// Serialize struct into a `String` using specified root tag name. +/// `root_tag` should be valid [XML name], otherwise error is returned. +/// +/// # Examples +/// +/// ``` +/// # use quick_xml::se::to_string_with_root; +/// # use serde::Serialize; +/// # use pretty_assertions::assert_eq; +/// #[derive(Serialize)] +/// struct Root<'a> { +/// #[serde(rename = "@attribute")] +/// attribute: &'a str, +/// element: &'a str, +/// #[serde(rename = "$text")] +/// text: &'a str, +/// } +/// +/// let data = Root { +/// attribute: "attribute content", +/// element: "element content", +/// text: "text content", +/// }; +/// +/// assert_eq!( +/// to_string_with_root("top-level", &data).unwrap(), +/// "\ +/// element content\ +/// text content\ +/// " +/// ); +/// ``` +/// +/// [XML name]: https://www.w3.org/TR/REC-xml/#NT-Name +pub fn to_string_with_root(root_tag: &str, value: &T) -> Result +where + T: ?Sized + Serialize, +{ + to_writer_with_root(String::new(), root_tag, value) +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /// Defines which characters would be escaped in [`Text`] events and attribute