Skip to main content

tanuki_common/
macros.rs

1#[macro_export]
2macro_rules! property {
3    attr($namespace:ty, $kind:ident, key = $key:expr) (
4        $( #[ $meta:meta ] )*
5        pub $itemty:tt $ident:ident $rest:tt $($semicolon:tt)?
6    ) => {
7        #[derive(Debug, Clone, PartialEq, $crate::_serde::Serialize, $crate::_serde::Deserialize)]
8        $( #[ $meta ] )*
9        pub $itemty $ident $rest $($semicolon)?
10
11        impl $crate::Property for $ident {
12            const KEY: &str = $key;
13            const KIND: $crate::property::PropertyKind = $crate::property::PropertyKind::$kind;
14        }
15
16        impl $namespace for $ident {}
17    };
18}
19
20#[cfg(test)]
21mod tests {
22
23    #[test]
24    fn properties() {
25        use crate::Property;
26
27        #[expect(unused)]
28        trait TestProperty: Property {}
29
30        #[property(TestProperty, State, key = "foo")]
31        pub struct Foo(pub u32);
32
33        assert_eq!(Foo::KEY, "foo");
34        assert_eq!(serde_json::to_value(Foo(42)).unwrap(), serde_json::json!(42));
35
36        #[property(TestProperty, State, key = "bar")]
37        pub struct Bar {
38            pub name: String,
39            pub value: f64,
40        }
41
42        assert_eq!(Bar::KEY, "bar");
43        assert_eq!(
44            serde_json::to_value(Bar {
45                name: "example".to_owned(),
46                value: 21.4,
47            })
48            .unwrap(),
49            serde_json::json!({
50                "name": "example",
51                "value": 21.4,
52            }),
53        );
54    }
55}