system_harness_macros/
lib.rs1use proc_macro::TokenStream;
2use syn::{
3 parse_macro_input, spanned::Spanned, AttrStyle, Attribute,
4 DeriveInput, LitStr
5};
6
7type Result<T> = std::result::Result<T, syn::Error>;
8
9mod properties;
10mod property_value;
11mod property_list;
12mod backends;
13
14#[proc_macro_derive(PropertyList)]
15pub fn property_list(input: TokenStream) -> TokenStream {
16 let derive_input = parse_macro_input!(input as DeriveInput);
17 match property_list::implement(&derive_input) {
18 Ok(props) => props.into(),
19 Err(err) => err.into_compile_error().into(),
20 }
21}
22
23#[proc_macro_derive(Backend)]
24pub fn backend(input: TokenStream) -> TokenStream {
25 let derive_input = parse_macro_input!(input as DeriveInput);
26 match backends::implement(&derive_input) {
27 Ok(props) => props.into(),
28 Err(err) => err.into_compile_error().into(),
29 }
30}
31
32#[proc_macro_derive(PropertyValue)]
33pub fn property_value(input: TokenStream) -> TokenStream {
34 let derive_input = parse_macro_input!(input as DeriveInput);
35 match property_value::implement(&derive_input) {
36 Ok(value) => value.into(),
37 Err(err) => err.into_compile_error().into(),
38 }
39}
40
41enum SerdeAttribute {
42 Flatten,
43 Rename(LitStr)
44}
45
46impl SerdeAttribute {
47
48 fn parse(attrs: &[Attribute]) -> Option<SerdeAttribute> {
50 let mut flatten = false;
51 let mut rename = None;
52 for attr in attrs {
53 match attr.style {
54 AttrStyle::Outer => match &attr.meta {
55 syn::Meta::List(list) if list.path.is_ident("serde") => {
56 let _ = attr.parse_nested_meta(|meta| {
57 if meta.path.is_ident("flatten") {
58 flatten = true;
59 } else if meta.path.is_ident("rename") {
60 let value = meta.value()?;
61 let s: LitStr = value.parse()?;
62 rename = Some(LitStr::new(&s.value(), attr.span()));
63 }
64 Ok(())
65 });
66 }
67 _ => {}
68 },
69 _ => {}
70 };
71 }
72 if flatten {
73 Some(SerdeAttribute::Flatten)
74 } else if let Some(rename) = rename {
75 Some(SerdeAttribute::Rename(rename))
76 } else {
77 None
78 }
79 }
80
81}