penguin_config_derive/
lib.rs

1use proc_macro::TokenStream;
2use syn::{parse_macro_input, DeriveInput};
3use quote::quote;
4
5use darling::FromDeriveInput;
6
7#[derive(FromDeriveInput)]
8#[darling(attributes(penguin_config))]
9struct Opts {
10    path: String,
11}
12
13const ERROR_MSG: &str = r#"penguin_config: invalid macro attributes.
14        Usage:
15            #[penguin_config(path = "path/to/json_file.json")]
16        "#;
17
18
19#[proc_macro_derive(PenguinConfigFile, attributes(penguin_config))]
20pub fn derive(input: TokenStream) -> TokenStream {
21    let input: DeriveInput = parse_macro_input!(input as DeriveInput);
22    let opts = Opts::from_derive_input(&input).expect(ERROR_MSG);
23
24    let file_path = opts.path;
25    let ident = input.ident;
26
27    let output = quote! {
28        impl PenguinConfig for #ident {
29            fn read_config() -> Self {
30                Deserializer::file_path(#file_path).deserialize()
31            }
32        }
33    };
34
35    output.into()
36}
37
38
39
40
41// Generates a json file from the structure at the given path. Requires a default implementation of
42// the structure.
43#[proc_macro_derive(PenguinConfigGenerate, attributes(penguin_config))]
44pub fn generate(input: TokenStream) -> TokenStream {
45    let input: DeriveInput = parse_macro_input!(input as DeriveInput);
46    let opts = Opts::from_derive_input(&input).expect(ERROR_MSG);
47
48    let file_path = opts.path;
49    let ident = input.ident;
50
51    let output = quote! {
52        impl PenguinConfigGenerate for #ident {
53            fn generate_penguin_config_file() {
54                Serializer::file_path(#file_path).serialize(&Self::default())
55            }
56        }
57    };
58
59    output.into()
60}
61