quick-xml icon indicating copy to clipboard operation
quick-xml copied to clipboard

How to pretty-print with serde?

Open troelsarvin opened this issue 3 years ago • 1 comments

Hello,

I have the code below; when it runs, it results in the following output:

seralized:
<osm><node visible="true" timestamp="2022-02-17T13:55:16.184553291Z"><tag k="key1" v="value1"/><tag k="key2" v="value2"/></node></osm>

I would like to print it in a prettyfied way, i.e. with indention and line breaks following the XML structure. How can that be done?

use serde::Serialize;
use quick_xml::se;
use chrono::{ DateTime, Utc };

#[derive(Serialize, Clone, Debug)]
#[serde(rename = "tag")]
#[serde(rename_all = "lowercase")]
struct OsmTag {
    k: String,
    v: String,
}

#[derive(Serialize, Clone, Debug)]
#[serde(rename = "node")]
#[serde(rename_all = "lowercase")]
struct OsmNode {
    #[serde(skip_serializing_if = "Option::is_none")]
    id: Option<u64>,
    visible: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    version: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    changeset: Option<u64>,
    timestamp: DateTime<Utc>,
    #[serde(skip_serializing_if = "Option::is_none")]
    user: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    uid: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    lat: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    lon: Option<f64>,
    tag: Vec<OsmTag>,
}

impl Default for OsmNode {
    fn default() -> OsmNode {
        OsmNode {
            id: None,
            visible: true,
            version: None,
            changeset: None,
            timestamp: Utc::now(),
            user: None,
            uid: None,
            lat: None,
            lon: None,
            tag: Vec::new()
        }
    }
}

#[derive(Serialize, Debug)]
#[serde(rename = "osm")]
#[serde(rename_all = "lowercase")]
struct OsmNodeContainer {
    node: OsmNode,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut on = OsmNode { ..Default::default() };
    let t1 = OsmTag { k: String::from("key1"), v: String::from("value1") };
    let t2 = OsmTag { k: String::from("key2"), v: String::from("value2") };
    on.tag.push(t1.clone());
    on.tag.push(t2.clone());
    let onc = OsmNodeContainer { node: on.clone(), };
    let ser = se::to_string(&onc)?;
    println!("seralized:");
    println!("{}", ser);

    Ok(())
}

troelsarvin avatar Feb 17 '22 14:02 troelsarvin

Pretty-printing not supported yet, PR is welcome. Be noted, however, that I plan a big rework of a serializer in the coming months

Mingun avatar May 21 '22 18:05 Mingun

When #490 will be merged, pretty-print will work

Mingun avatar Oct 02 '22 14:10 Mingun

When #490 will be merged, pretty-print will work

Can you please explain how it's meant to work? I didn't find any API for pretty-print serialization.

thanks!

gdesmott avatar Apr 12 '23 14:04 gdesmott

Create Serializer and setup indent

Mingun avatar Apr 12 '23 15:04 Mingun

For anyone who needs a quick example of adding indentation when do serializing

    use serde::Serialize;
    use quick_xml::se::Serializer;

    #[derive(Debug, PartialEq, Serialize)]
    struct Struct {
        question: String,
        answer: u32,
    }

    let data = Struct {
        question: "The Ultimate Question of Life, the Universe, and Everything".into(),
        answer: 42,
    };

    let mut buffer = String::new();
    let mut ser = Serializer::new(&mut buffer);
    ser.indent(' ', 2);

    data.serialize(ser).unwrap();

    println!("{buffer}");

noguxun avatar Apr 15 '23 10:04 noguxun

@noguxun, feel free to make a PR that improves documentation (example for indent and maybe a mention in Serializer doc)

Mingun avatar Apr 15 '23 16:04 Mingun