| use serde::de::value::Error; |
| use serde::{ser, Serialize}; |
| type Result<T> = ::std::result::Result<T, Error>; |
|
|
| pub struct Serializer { |
| |
| output: String, |
| |
| num_elements: Vec<usize>, |
| max_elements: usize, |
| level: usize, |
| max_depth: usize, |
| |
| |
| max_string: usize, |
| } |
|
|
| |
| |
| |
| |
| |
| pub fn to_string<T>(value: &T) -> Result<String> |
| where |
| T: Serialize, |
| { |
| let max_depth = 20; |
| let max_elements = 6; |
| let max_string = 100; |
| let mut serializer = Serializer { |
| output: String::new(), |
| level: 0, |
| max_depth, |
| max_elements, |
| num_elements: vec![0; max_depth], |
| max_string, |
| }; |
| value.serialize(&mut serializer)?; |
| Ok(serializer.output) |
| } |
|
|
| pub fn repr<T>(value: &T) -> Result<String> |
| where |
| T: Serialize, |
| { |
| let max_depth = 200; |
| let max_string = usize::MAX; |
| let mut serializer = Serializer { |
| output: String::new(), |
| level: 0, |
| max_depth, |
| max_elements: 100, |
| num_elements: vec![0; max_depth], |
| max_string, |
| }; |
| value.serialize(&mut serializer)?; |
| Ok(serializer.output) |
| } |
|
|
| impl<'a> ser::Serializer for &'a mut Serializer { |
| |
| |
| |
| |
| |
| |
| type Ok = (); |
|
|
| |
| type Error = Error; |
|
|
| |
| |
| |
| |
| type SerializeSeq = Self; |
| type SerializeTuple = Self; |
| type SerializeTupleStruct = Self; |
| type SerializeTupleVariant = Self; |
| type SerializeMap = Self; |
| type SerializeStruct = Self; |
| type SerializeStructVariant = Self; |
|
|
| |
| |
| |
| fn serialize_bool(self, v: bool) -> Result<()> { |
| self.output += if v { "True" } else { "False" }; |
| Ok(()) |
| } |
|
|
| |
| |
| |
| |
| fn serialize_i8(self, v: i8) -> Result<()> { |
| self.serialize_i64(i64::from(v)) |
| } |
|
|
| fn serialize_i16(self, v: i16) -> Result<()> { |
| self.serialize_i64(i64::from(v)) |
| } |
|
|
| fn serialize_i32(self, v: i32) -> Result<()> { |
| self.serialize_i64(i64::from(v)) |
| } |
|
|
| |
| |
| fn serialize_i64(self, v: i64) -> Result<()> { |
| self.output += &v.to_string(); |
| Ok(()) |
| } |
|
|
| fn serialize_u8(self, v: u8) -> Result<()> { |
| self.serialize_u64(u64::from(v)) |
| } |
|
|
| fn serialize_u16(self, v: u16) -> Result<()> { |
| self.serialize_u64(u64::from(v)) |
| } |
|
|
| fn serialize_u32(self, v: u32) -> Result<()> { |
| self.serialize_u64(u64::from(v)) |
| } |
|
|
| fn serialize_u64(self, v: u64) -> Result<()> { |
| self.output += &v.to_string(); |
| Ok(()) |
| } |
|
|
| fn serialize_f32(self, v: f32) -> Result<()> { |
| self.serialize_f64(f64::from(v)) |
| } |
|
|
| fn serialize_f64(self, v: f64) -> Result<()> { |
| self.output += &v.to_string(); |
| Ok(()) |
| } |
|
|
| |
| |
| fn serialize_char(self, v: char) -> Result<()> { |
| self.serialize_str(&v.to_string()) |
| } |
|
|
| |
| |
| |
| fn serialize_str(self, v: &str) -> Result<()> { |
| self.output += "\""; |
| if v.len() > self.max_string { |
| self.output += &v[..self.max_string]; |
| self.output += "..."; |
| } else { |
| self.output += v; |
| } |
| self.output += "\""; |
| Ok(()) |
| } |
|
|
| |
| |
| |
| fn serialize_bytes(self, v: &[u8]) -> Result<()> { |
| use serde::ser::SerializeSeq; |
| let mut seq = self.serialize_seq(Some(v.len()))?; |
| for byte in v { |
| seq.serialize_element(byte)?; |
| } |
| seq.end() |
| } |
|
|
| |
| fn serialize_none(self) -> Result<()> { |
| self.serialize_unit() |
| } |
|
|
| |
| |
| |
| |
| |
| fn serialize_some<T>(self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| value.serialize(self) |
| } |
|
|
| |
| |
| fn serialize_unit(self) -> Result<()> { |
| self.output += "None"; |
| Ok(()) |
| } |
|
|
| |
| |
| |
| fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { |
| self.serialize_unit() |
| } |
|
|
| |
| |
| |
| |
| fn serialize_unit_variant( |
| self, |
| _name: &'static str, |
| _variant_index: u32, |
| variant: &'static str, |
| ) -> Result<()> { |
| |
| self.output += variant; |
| Ok(()) |
| } |
|
|
| |
| |
| fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| value.serialize(self) |
| } |
|
|
| |
| |
| |
| |
| |
| fn serialize_newtype_variant<T>( |
| self, |
| _name: &'static str, |
| _variant_index: u32, |
| variant: &'static str, |
| value: &T, |
| ) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| |
| self.output += variant; |
| self.output += "("; |
| value.serialize(&mut *self)?; |
| self.output += ")"; |
| Ok(()) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { |
| self.output += "["; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
|
|
| |
| |
| |
| |
| fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { |
| self.output += "("; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
|
|
| |
| fn serialize_tuple_struct( |
| self, |
| _name: &'static str, |
| len: usize, |
| ) -> Result<Self::SerializeTupleStruct> { |
| self.serialize_tuple(len) |
| } |
|
|
| |
| |
| fn serialize_tuple_variant( |
| self, |
| _name: &'static str, |
| _variant_index: u32, |
| variant: &'static str, |
| _len: usize, |
| ) -> Result<Self::SerializeTupleVariant> { |
| |
| self.output += variant; |
| self.output += "("; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
|
|
| |
| fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { |
| self.output += "{"; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
|
|
| |
| |
| |
| |
| |
| fn serialize_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { |
| |
| |
| if let Some(stripped) = name.strip_suffix("Helper") { |
| self.output += stripped; |
| } else { |
| self.output += name |
| } |
| self.output += "("; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
|
|
| |
| |
| fn serialize_struct_variant( |
| self, |
| _name: &'static str, |
| _variant_index: u32, |
| variant: &'static str, |
| _len: usize, |
| ) -> Result<Self::SerializeStructVariant> { |
| |
| self.output += variant; |
| self.output += "("; |
| self.level = std::cmp::min(self.max_depth - 1, self.level + 1); |
| self.num_elements[self.level] = 0; |
| Ok(self) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| impl<'a> ser::SerializeSeq for &'a mut Serializer { |
| |
| type Ok = (); |
| |
| type Error = Error; |
|
|
| |
| fn serialize_element<T>(&mut self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| self.num_elements[self.level] += 1; |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| if !self.output.ends_with('[') { |
| self.output += ", "; |
| } |
| value.serialize(&mut **self) |
| } else { |
| if num_elements == self.max_elements { |
| self.output += ", ..."; |
| } |
| Ok(()) |
| } |
| } |
|
|
| |
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += "]"; |
| Ok(()) |
| } |
| } |
|
|
| |
| impl<'a> ser::SerializeTuple for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| fn serialize_element<T>(&mut self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| self.num_elements[self.level] += 1; |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| if !self.output.ends_with('(') { |
| self.output += ", "; |
| } |
| value.serialize(&mut **self) |
| } else { |
| if num_elements == self.max_elements { |
| self.output += ", ..."; |
| } |
| Ok(()) |
| } |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += ")"; |
| Ok(()) |
| } |
| } |
|
|
| |
| impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| fn serialize_field<T>(&mut self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| self.num_elements[self.level] += 1; |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| if !self.output.ends_with('(') { |
| self.output += ", "; |
| } |
| value.serialize(&mut **self) |
| } else { |
| if num_elements == self.max_elements { |
| self.output += ", ..."; |
| } |
| Ok(()) |
| } |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += ")"; |
| Ok(()) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| fn serialize_field<T>(&mut self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| self.num_elements[self.level] += 1; |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| if !self.output.ends_with('(') { |
| self.output += ", "; |
| } |
| value.serialize(&mut **self) |
| } else { |
| if num_elements == self.max_elements { |
| self.output += ", ..."; |
| } |
| Ok(()) |
| } |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += ")"; |
| Ok(()) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| impl<'a> ser::SerializeMap for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| fn serialize_key<T>(&mut self, key: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| self.num_elements[self.level] += 1; |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| if !self.output.ends_with('{') { |
| self.output += ", "; |
| } |
| key.serialize(&mut **self) |
| } else { |
| if num_elements == self.max_elements { |
| self.output += ", ..."; |
| } |
| Ok(()) |
| } |
| } |
|
|
| |
| |
| |
| fn serialize_value<T>(&mut self, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| let num_elements = self.num_elements[self.level]; |
| if num_elements < self.max_elements { |
| self.output += ":"; |
| value.serialize(&mut **self) |
| } else { |
| Ok(()) |
| } |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += "}"; |
| Ok(()) |
| } |
| } |
|
|
| |
| |
| impl<'a> ser::SerializeStruct for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| if !self.output.ends_with('(') { |
| self.output += ", "; |
| } |
| |
| if key != "type" { |
| self.output += key; |
| self.output += "="; |
| value.serialize(&mut **self) |
| } else { |
| Ok(()) |
| } |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += ")"; |
| Ok(()) |
| } |
| } |
|
|
| |
| |
| impl<'a> ser::SerializeStructVariant for &'a mut Serializer { |
| type Ok = (); |
| type Error = Error; |
|
|
| fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> |
| where |
| T: ?Sized + Serialize, |
| { |
| if !self.output.ends_with('(') { |
| self.output += ", "; |
| } |
| |
| self.output += key; |
| self.output += "="; |
| value.serialize(&mut **self) |
| } |
|
|
| fn end(self) -> Result<()> { |
| self.num_elements[self.level] = 0; |
| self.level = self.level.saturating_sub(1); |
| self.output += ")"; |
| Ok(()) |
| } |
| } |
|
|
| |
|
|
| #[test] |
| fn test_basic() { |
| assert_eq!(to_string(&true).unwrap(), "True"); |
| assert_eq!(to_string(&Some(1)).unwrap(), "1"); |
| assert_eq!(to_string(&None::<usize>).unwrap(), "None"); |
| } |
|
|
| #[test] |
| fn test_struct() { |
| #[derive(Serialize)] |
| struct Test { |
| int: u32, |
| seq: Vec<&'static str>, |
| } |
|
|
| let test = Test { |
| int: 1, |
| seq: vec!["a", "b"], |
| }; |
| let expected = r#"Test(int=1, seq=["a", "b"])"#; |
| assert_eq!(to_string(&test).unwrap(), expected); |
| } |
|
|
| #[test] |
| fn test_enum() { |
| #[derive(Serialize)] |
| enum E { |
| Unit, |
| Newtype(u32), |
| Tuple(u32, u32), |
| Struct { a: u32 }, |
| } |
|
|
| let u = E::Unit; |
| let expected = r#"Unit"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
|
|
| let n = E::Newtype(1); |
| let expected = r#"Newtype(1)"#; |
| assert_eq!(to_string(&n).unwrap(), expected); |
|
|
| let t = E::Tuple(1, 2); |
| let expected = r#"Tuple(1, 2)"#; |
| assert_eq!(to_string(&t).unwrap(), expected); |
|
|
| let s = E::Struct { a: 1 }; |
| let expected = r#"Struct(a=1)"#; |
| assert_eq!(to_string(&s).unwrap(), expected); |
| } |
|
|
| #[test] |
| fn test_enum_untagged() { |
| #[derive(Serialize)] |
| #[serde(untagged)] |
| enum E { |
| Unit, |
| Newtype(u32), |
| Tuple(u32, u32), |
| Struct { a: u32 }, |
| } |
|
|
| let u = E::Unit; |
| let expected = r#"None"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
|
|
| let n = E::Newtype(1); |
| let expected = r#"1"#; |
| assert_eq!(to_string(&n).unwrap(), expected); |
|
|
| let t = E::Tuple(1, 2); |
| let expected = r#"(1, 2)"#; |
| assert_eq!(to_string(&t).unwrap(), expected); |
|
|
| let s = E::Struct { a: 1 }; |
| let expected = r#"E(a=1)"#; |
| assert_eq!(to_string(&s).unwrap(), expected); |
| } |
|
|
| #[test] |
| fn test_struct_tagged() { |
| #[derive(Serialize)] |
| #[serde(untagged)] |
| enum E { |
| A(A), |
| } |
|
|
| #[derive(Serialize)] |
| #[serde(tag = "type")] |
| struct A { |
| a: bool, |
| b: usize, |
| } |
|
|
| let u = A { a: true, b: 1 }; |
| |
| |
| let expected = r#"A(a=True, b=1)"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
|
|
| let u = E::A(A { a: true, b: 1 }); |
| let expected = r#"A(a=True, b=1)"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
| } |
|
|
| #[test] |
| fn test_flatten() { |
| #[derive(Serialize)] |
| struct A { |
| a: bool, |
| b: usize, |
| } |
|
|
| #[derive(Serialize)] |
| struct B { |
| c: A, |
| d: usize, |
| } |
|
|
| #[derive(Serialize)] |
| struct C { |
| #[serde(flatten)] |
| c: A, |
| d: usize, |
| } |
|
|
| #[derive(Serialize)] |
| #[serde(transparent)] |
| struct D { |
| e: A, |
| } |
|
|
| let u = B { |
| c: A { a: true, b: 1 }, |
| d: 2, |
| }; |
| let expected = r#"B(c=A(a=True, b=1), d=2)"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
|
|
| let u = C { |
| c: A { a: true, b: 1 }, |
| d: 2, |
| }; |
| |
| |
| |
| let expected = r#"{"a":True, "b":1, "d":2}"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
|
|
| let u = D { |
| e: A { a: true, b: 1 }, |
| }; |
| let expected = r#"A(a=True, b=1)"#; |
| assert_eq!(to_string(&u).unwrap(), expected); |
| } |
|
|