#![cfg(feature = "serde")] use std::collections::{BTreeMap, HashMap}; use serde::Serialize; use struson::{ serde::JsonWriterSerializer, writer::{JsonStreamWriter, JsonWriter}, }; fn assert_serialized(s: S, expected_json: &str) { let mut writer = Vec::::new(); let mut json_writer = JsonStreamWriter::new(&mut writer); let mut serializer = JsonWriterSerializer::new(&mut json_writer); s.serialize(&mut serializer).unwrap(); json_writer.finish_document().unwrap(); let json = String::from_utf8(writer).unwrap(); assert_eq!(expected_json, json); let serde_json = serde_json::to_string(&s).unwrap(); assert_eq!( expected_json, serde_json, "Serde JSON output does not match expected JSON" ); } #[test] fn serialize_map() { // Use BTreeMap for consistent entry order assert_serialized( BTreeMap::from([("a", vec![1, 2]), ("b", vec![3, 4])]), r#"{"a":[1,2],"b":[3,4]}"#, ); assert_serialized(HashMap::from([(1, 2)]), r#"{"1":2}"#); } #[test] fn serialize_newtype_struct() { #[derive(Serialize)] struct S(Vec); assert_serialized(S(vec![1, 2]), "[1,2]"); } #[test] fn serialize_newtype_variant() { #[derive(Serialize)] enum E { A(Vec), } assert_serialized(E::A(vec![1, 2]), r#"{"A":[1,2]}"#); } #[test] fn serialize_option() { assert_serialized(vec![None, Some(1)], "[null,1]"); // Ambiguity for values which are themselves serialized as `null` assert_serialized(vec![None, Some(())], "[null,null]"); } #[test] fn serialize_struct() { #[derive(Serialize)] struct S { a: u64, b: bool, c: Vec, } assert_serialized( S { a: 1, b: true, c: vec![S { a: 2, b: false, c: Vec::new(), }], }, r#"{"a":1,"b":true,"c":[{"a":2,"b":false,"c":[]}]}"#, ); } #[test] fn serialize_struct_variant() { #[derive(Serialize)] enum E { A { a: i8, b: String }, } assert_serialized( E::A { a: -3, b: "test".to_owned(), }, r#"{"A":{"a":-3,"b":"test"}}"#, ); } #[test] fn serialize_tuple() { assert_serialized((true, 1, "test"), r#"[true,1,"test"]"#); } #[test] fn serialize_tuple_struct() { #[derive(Serialize)] struct S(bool, Vec, &'static str); assert_serialized(S(true, vec![1], "test"), r#"[true,[1],"test"]"#); } #[test] fn serialize_tuple_variant() { #[derive(Serialize)] enum E { A(bool, i8), } assert_serialized(E::A(true, -3), r#"{"A":[true,-3]}"#); } #[test] fn serialize_unit() { assert_serialized((), "null"); } #[test] fn serialize_unit_struct() { #[derive(Serialize)] struct S; assert_serialized(S, "null"); } #[test] fn serialize_unit_variant() { #[derive(Serialize)] enum E { A, } assert_serialized(E::A, "\"A\""); } #[test] fn serialize_skipped_field() { #[derive(Serialize)] struct S { a: u32, #[allow(dead_code)] #[serde(skip)] b: u32, } assert_serialized(S { a: 1, b: 2 }, r#"{"a":1}"#); } #[test] fn serialize_conditional_skipped_field() { #[derive(Serialize)] struct S { a: u32, #[serde(skip_serializing_if = "Option::is_none")] b: Option, } assert_serialized(S { a: 1, b: Some(2) }, r#"{"a":1,"b":2}"#); assert_serialized(S { a: 1, b: None }, r#"{"a":1}"#); #[derive(Serialize)] enum E { S { a: u32, #[serde(skip_serializing_if = "Option::is_none")] b: Option, }, } assert_serialized(E::S { a: 1, b: Some(2) }, r#"{"S":{"a":1,"b":2}}"#); assert_serialized(E::S { a: 1, b: None }, r#"{"S":{"a":1}}"#); }