Skip to main content

anodized_core/instrument/
data.rs

1#[cfg(test)]
2#[path = "data_tests.rs"]
3mod data_tests;
4
5use proc_macro2::TokenStream;
6use quote::ToTokens;
7use syn::{ItemEnum, ItemImpl, ItemStruct, Result, parse_quote};
8
9use crate::{DataSpec, instrument::Mode};
10
11impl Mode {
12    pub fn instrument_item_struct(
13        &self,
14        spec: DataSpec,
15        item_struct: ItemStruct,
16    ) -> Result<TokenStream> {
17        let mut tokens = TokenStream::new();
18
19        item_struct.to_tokens(&mut tokens);
20
21        if self.changes_anything() {
22            let ident = &item_struct.ident;
23            let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();
24            let statements = Self::build_precondition_fn_body(&[], &spec.maintains).stmts;
25
26            let spec_impl: ItemImpl = parse_quote! {
27                #[doc(hidden)]
28                #[allow(warnings)]
29                impl #impl_generics #ident #ty_generics #where_clause {
30                    fn __anodized_data_maintains(&self) -> bool {
31                        #(#statements)*
32                    }
33                }
34            };
35            spec_impl.to_tokens(&mut tokens);
36        }
37
38        Ok(tokens)
39    }
40
41    pub fn instrument_item_enum(&self, spec: DataSpec, item_enum: ItemEnum) -> Result<TokenStream> {
42        let mut tokens = TokenStream::new();
43
44        let ident = &item_enum.ident;
45        let (impl_generics, ty_generics, where_clause) = item_enum.generics.split_for_impl();
46        let statements = Self::build_precondition_fn_body(&[], &spec.maintains).stmts;
47
48        item_enum.to_tokens(&mut tokens);
49
50        if let Mode::EmbedSpecs = self {
51            let spec_impl: ItemImpl = parse_quote! {
52                #[doc(hidden)]
53                #[allow(warnings)]
54                impl #impl_generics #ident #ty_generics #where_clause {
55                    fn __anodized_data_maintains(&self) -> bool {
56                        // Bring all variants into scope for convenience.
57                        use #ident::*;
58                        #(#statements)*
59                    }
60                }
61            };
62            spec_impl.to_tokens(&mut tokens);
63        }
64
65        Ok(tokens)
66    }
67}