Skip to main content

optionize_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3
4mod optionize;
5
6#[proc_macro_attribute]
7pub fn optionized(args: TokenStream, input: TokenStream) -> TokenStream {
8    let input = input.into();
9    optionize::proc(args.into(), &input)
10        .unwrap_or_else(|e| {
11            let e = e.write_errors();
12            quote! {
13                #input
14                #e
15            }
16        })
17        .into()
18}
19
20#[proc_macro_derive(Optionize, attributes(optionize))]
21pub fn derive(_: TokenStream) -> TokenStream {
22    Default::default()
23}
24
25// Derive inputs have already been processed by rustc's cfg expansion. Discard
26// the intermediate declaration and re-emit that input for the attribute macro,
27// which may still need to remove skipped fields from an existing object.
28#[doc(hidden)]
29#[proc_macro_derive(Prepare, attributes(optionize))]
30pub fn prepare(input: TokenStream) -> TokenStream {
31    let mut input = syn::parse_macro_input!(input as syn::DeriveInput);
32    debug_assert!(
33        input.attrs[0]
34            .path()
35            .segments
36            .last()
37            .is_some_and(|seg| seg.ident == "discard")
38    );
39    input.attrs.remove(0); // The discard attribute inserted by optionized.
40    quote!(#input).into()
41}
42
43#[doc(hidden)]
44#[proc_macro_attribute]
45pub fn discard(_: TokenStream, _: TokenStream) -> TokenStream {
46    Default::default()
47}
48
49#[doc(hidden)]
50#[proc_macro_attribute]
51pub fn expand(args: TokenStream, input: TokenStream) -> TokenStream {
52    let input = input.into();
53    optionize::expand(args.into(), &input)
54        .unwrap_or_else(|error| error.write_errors())
55        .into()
56}