Open dishmaker opened 6 months ago
// [package] // name = "xml_vs_json" // version = "0.1.0" // edition = "2021" // [dependencies] // eyre = "0.6.12" // quick-xml = { version = "0.31.0", features = ["serde", "serialize"] } // rmp-serde = "1.1.2" // serde = { version = "1.0.197", features = ["derive"] } // serde-xml-rs = "0.6.0" // serde_json = "1.0.114" // serde_yaml = "0.9.32" // toml = "0.8.10" use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct MyStruct { pub i8_value: i8, pub choice_value: MyChoice, pub choice_list: Vec<MyChoice>, } #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub enum MyChoice { ChoiceA(MyChoiceA), ChoiceB(MyChoiceB), } #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct MyChoiceA { pub choice_i32: i32, } #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] pub struct MyChoiceB { pub choice_i64: i64, pub choice_text: String, } fn main() { let result = run(); if let Err(err) = result { println!("err: {err}"); } } fn run() -> eyre::Result<()> { let a = MyStruct { i8_value: 8, choice_value: MyChoice::ChoiceA(MyChoiceA { choice_i32: 32 }), choice_list: vec![ MyChoice::ChoiceA(MyChoiceA { choice_i32: 32 }), MyChoice::ChoiceB(MyChoiceB { choice_i64: 64, choice_text: "my text".to_string(), }), MyChoice::ChoiceA(MyChoiceA { choice_i32: 32 }), ], }; try_reencode_all(&a)?; Ok(()) } fn try_reencode_all(a: &MyStruct) -> eyre::Result<()> { // pass let a_json = reencode_json(&a)?; assert_eq!(a, &a_json); // pass let a_toml = reencode_toml(&a)?; assert_eq!(a, &a_toml); // pass let a_yaml = reencode_yaml(&a)?; assert_eq!(a, &a_yaml); // pass let a_msgpack = reencode_msgpack(&a)?; assert_eq!(a, &a_msgpack); // fail: does not encode second value in the list let a_xml = reencode_xml(&a)?; assert_eq!(a, &a_xml); // fail: Unsupported operation: cannot serialize enum newtype variant `MyChoice::ChoiceA` let a_qxml = reencode_quick_xml(&a)?; assert_eq!(a, &a_qxml); Ok(()) } fn reencode_json(input: &MyStruct) -> eyre::Result<MyStruct> { let json_str: String = serde_json::to_string(&input)?; println!("serde_json: {json_str}"); let output = serde_json::from_str(&json_str)?; Ok(output) } fn reencode_toml(input: &MyStruct) -> eyre::Result<MyStruct> { let toml_str: String = toml::to_string(&input)?; println!("toml: {toml_str}"); let output = toml::from_str(&toml_str)?; Ok(output) } fn reencode_yaml(input: &MyStruct) -> eyre::Result<MyStruct> { let yaml_str: String = serde_yaml::to_string(&input)?; println!("yaml: {yaml_str}"); let output = serde_yaml::from_str(&yaml_str)?; Ok(output) } fn reencode_msgpack(input: &MyStruct) -> eyre::Result<MyStruct> { let msgpack_bytes: Vec<u8> = rmp_serde::to_vec(&input)?; println!("rmp_serde: {msgpack_bytes:?}"); let output = rmp_serde::from_slice(&msgpack_bytes)?; Ok(output) } fn reencode_xml(input: &MyStruct) -> eyre::Result<MyStruct> { let xml_str: String = serde_xml_rs::to_string(&input)?; println!("serde_xml_rs: {xml_str}"); // decodes only one element let output = serde_xml_rs::from_str(&xml_str)?; Ok(output) } fn reencode_quick_xml(input: &MyStruct) -> eyre::Result<MyStruct> { // serialization does not work let qxml_str: String = quick_xml::se::to_string(&input)?; println!("quick_xml::se: {qxml_str}"); let output = quick_xml::de::from_str(&qxml_str)?; Ok(output) }
It partially works - encodes only the first value in the list.