use std::collections::HashMap; use descriptor::{object_describe_to_string, Descriptor}; pub fn no_color(str: String) -> String { String::from_utf8(strip_ansi_escapes::strip(str).unwrap()).unwrap() } #[test] fn test_flatten() { #[derive(Descriptor)] struct Foo { loooooooong: String, #[descriptor(flatten)] child: ChildFoo, } #[derive(Descriptor)] struct ChildFoo { twoooo: String, #[descriptor(flatten)] child: GrandKid, } #[derive(Descriptor)] struct GrandKid { one: String, } let description = object_describe_to_string(&Foo { loooooooong: "one".to_string(), child: ChildFoo { twoooo: "two".to_string(), child: GrandKid { one: "tee".to_string(), }, }, }) .unwrap(); assert_eq!( r#" Loooooooong: one Twoooo: two One: tee "#, description ); } #[test] fn test_func() { #[derive(Descriptor)] struct Foo { #[descriptor(map = map_test)] time: u64, #[descriptor(map = map_test, resolve_option)] optional_some: Option, #[descriptor(map = map_test, resolve_option)] optional_none: Option, } fn map_test(val: &u64) -> String { format!("{} seconds", val) } let description = object_describe_to_string(&Foo { time: 10000, optional_some: Some(10), optional_none: None, }) .unwrap(); assert_eq!( r#" Time: 10000 seconds Optional Some: 10 seconds Optional None: ~ "#, no_color(description) ); } #[test] fn test_vec() { #[derive(Descriptor)] struct Foo { list: Vec, string_list: Vec, } #[derive(Descriptor)] struct ListBar { first_field: String, child: FooChild, second: Vec, } #[derive(Descriptor)] struct FooChild { anything: String, } let table = object_describe_to_string(&Foo { list: vec![ ListBar { first_field: "first".to_string(), child: FooChild { anything: "any".to_string(), }, second: vec![FooChild { anything: "foo".to_string(), }], }, ListBar { first_field: "second".to_string(), child: FooChild { anything: "any".to_string(), }, second: vec![FooChild { anything: "foo".to_string(), }], }, ], string_list: vec!["test".to_string(), "test2".to_string()], }) .unwrap(); assert_eq!( r#" List: - First Field: first Child: Anything: any Second: - Anything: foo - First Field: second Child: Anything: any Second: - Anything: foo String List: - test - test2 "#, no_color(table) ); } #[test] fn test_into_struct_level() { #[derive(Descriptor)] #[descriptor(into = TestFromReceiver)] struct TestFrom { foo: String, bar: String, } #[derive(Descriptor)] struct TestFromReceiver { recv: String, } #[derive(Descriptor)] #[descriptor(into = TestIntoReceiver)] struct TestInto { foo_into: String, bar_into: String, } #[derive(Descriptor)] struct TestIntoReceiver { recv: String, } impl From<&TestFrom> for TestFromReceiver { fn from(e: &TestFrom) -> Self { Self { recv: format!("{}-{}", e.foo, e.bar), } } } impl Into for &TestInto { fn into(self) -> TestIntoReceiver { TestIntoReceiver { recv: format!("{}-{}", self.foo_into, self.bar_into), } } } let from = object_describe_to_string(&TestFrom { foo: "foo".to_string(), bar: "bar".to_string(), }) .unwrap(); println!("{}", from); assert_eq!("\nRecv: foo-bar\n", from); let into = object_describe_to_string(&TestInto { foo_into: "foo".to_string(), bar_into: "bar".to_string(), }) .unwrap(); assert_eq!("\nRecv: foo-bar\n", into) } #[test] fn test_into_field_level() { #[derive(Descriptor)] struct Foo { #[descriptor(into = Bar)] foo: FooInto, #[descriptor(into = Bar, map = FooInto::test)] bar: FooInto, } struct FooInto { foo: String, bar: String, } #[derive(Descriptor)] struct Bar { foo: String, } impl From<&FooInto> for Bar { fn from(f: &FooInto) -> Self { Self { foo: format!("{}-{}", f.foo, f.bar), } } } impl FooInto { fn test(&self) -> Bar { Bar { foo: format!("{}-{}", self.bar, self.foo), } } } let string = object_describe_to_string(&Foo { foo: FooInto { foo: "a".to_string(), bar: "b".to_string(), }, bar: FooInto { foo: "a".to_string(), bar: "b".to_string(), }, }) .unwrap(); println!("{}", string); assert_eq!("\nFoo:\n Foo: a-b\nBar:\n Foo: b-a\n", string) } #[test] fn test_table_description() { #[derive(Descriptor)] struct Foo { history_no_table: Vec, #[descriptor(output_table)] history: Vec, } #[derive(Descriptor, Clone)] struct InnerFoo { state: String, value: String, } let list = vec![ InnerFoo { state: "test".to_string(), value: "t".to_string(), }, InnerFoo { state: "t".to_string(), value: "test".to_string(), }, ]; let object = &Foo { history_no_table: list.clone(), history: list.clone(), }; let description = object_describe_to_string(object).unwrap(); assert_eq!( r#" History No Table: - State: test Value: t - State: t Value: test History: STATE VALUE test t t test "#, no_color(description) ); } #[test] fn test_describe_enum() { #[derive(Descriptor)] struct Foo { enum_field: Bar, enum_renamed: Bar, } #[derive(Descriptor)] enum Bar { SomeEnum, #[descriptor(rename_description = "Rename AnnotationValue")] AnotherRenamed, } let description = object_describe_to_string(&Foo { enum_field: Bar::SomeEnum, enum_renamed: Bar::AnotherRenamed, }) .unwrap(); assert_eq!( r#" Enum Field: SomeEnum Enum Renamed: Rename AnnotationValue "#, no_color(description) ); } #[test] fn test_extra_fields() { #[derive(Descriptor)] #[descriptor(extra_fields = ExtraFieldsStruct)] struct Foo { first_field: String, number: u32, } #[derive(Descriptor)] struct ExtraFieldsStruct { anything: String, } impl From<&Foo> for ExtraFieldsStruct { fn from(b: &Foo) -> Self { Self { anything: format!("{}-{}", b.first_field, b.number / 10), } } } let description = object_describe_to_string(&Foo { first_field: "test".to_string(), number: 200, }) .unwrap(); assert_eq!( r#" First Field: test Number: 200 Anything: test-20 "#, no_color(description) ); } #[test] fn test_map() { #[derive(Descriptor)] struct B { map: HashMap, } let mut map = HashMap::new(); map.insert("test".to_string(), "f".to_string()); map.insert("f".to_string(), "f".to_string()); let description = object_describe_to_string(&B { map }).unwrap(); assert_eq!( r#" Map: f: f test: f "#, no_color(description) ); }