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}