Skip to main content

fecund_font_flounder_macros/
lib.rs

1#![allow(unused_imports)]
2
3use proc_macro2::TokenStream;
4use quote::{quote, quote_spanned};
5use syn::spanned::Spanned;
6use syn::{
7    parse_macro_input, parse_quote, Data, DeriveInput, Fields, GenericParam, Generics, Index, Type,
8};
9use utils::{add_gen, div_gen, sub_gen};
10
11
12mod utils;
13
14
15///Naively implements the Add and AddAssign traits, adding every field to each other. 
16#[proc_macro_attribute]
17pub fn naive_add(_att: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
18    
19    let mut ory_item = item.clone();
20
21    let input = parse_macro_input!(item as DeriveInput);
22    let name = input.ident;
23    
24    let adding = add_gen(&input.data);
25        
26    let expanded = quote!{
27
28        impl std::ops::AddAssign for #name{
29           fn add_assign(&mut self, rhs: Self) {
30               #adding
31           } 
32        }
33
34        impl std::ops::Add for #name {
35            type Output = #name;
36            fn add(self, rhs: Self) -> Self::Output {
37                let mut mself = self;
38                mself += rhs;
39                mself
40            }
41        }
42
43    };
44    
45        
46    let t = proc_macro::TokenStream::from(expanded);
47
48    ory_item.extend(t);
49    ory_item
50
51}
52
53
54
55
56
57///Naively implements the Sub and SubAssign traits, adding every field to each other. 
58#[proc_macro_attribute]
59pub fn naive_sub(_att: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
60    
61    let mut ory_item = item.clone();
62
63    let input = parse_macro_input!(item as DeriveInput);
64    let name = input.ident;
65    
66    let subing = sub_gen(&input.data);
67        
68    let expanded = quote!{
69
70        impl std::ops::SubAssign for #name {
71           fn sub_assign(&mut self, rhs: Self) {
72               #subing
73           } 
74        }
75
76        impl std::ops::Sub for #name {
77            type Output = #name;
78            fn sub(self, rhs: Self) -> Self::Output {
79                let mut mself = self;
80                mself -= rhs;
81                mself
82            }
83        }
84
85    };
86    
87        
88    let t = proc_macro::TokenStream::from(expanded);
89
90    ory_item.extend(t);
91    ory_item
92
93}
94
95
96
97/// Naively implements the Div and DivAssign traits. Allows division by the given type in the
98/// attribute.
99#[proc_macro_attribute]
100pub fn naive_div(att: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
101    
102    let mut ory_item = item.clone();
103
104    let input = parse_macro_input!(item as DeriveInput);
105    let att = parse_macro_input!(att as Type);
106
107    let name = input.ident;
108    
109    let dividing = div_gen(&input.data);
110        
111    let expanded = quote!{
112
113        impl std::ops::DivAssign< #att > for #name {
114            fn div_assign(&mut self, rhs: #att ) {
115                #dividing
116            }
117        }
118        impl std::ops::Div< #att > for #name {
119            type Output = #name;
120            fn div(self, rhs: #att) -> Self::Output {
121                let mut mself = self;
122                mself /= rhs;
123                mself
124            }
125        }
126        
127    };
128
129
130    let t = proc_macro::TokenStream::from(expanded);
131
132    ory_item.extend(t);
133    ory_item
134
135}
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156//// Add a bound `T: HeapSize` to every type parameter T.
157//fn add_trait_bounds(mut generics: Generics) -> Generics {
158    //for param in &mut generics.params {
159        //if let GenericParam::Type(ref mut type_param) = *param {
160            //type_param.bounds.push(parse_quote!(heapsize::HeapSize));
161        //}
162    //}
163    //generics
164//}
165
166//// Generate an expression to sum up the heap size of each field.
167//fn heap_size_sum(data: &Data) -> TokenStream {
168    //match *data {
169        //Data::Struct(ref data) => {
170            //match data.fields {
171                //Fields::Named(ref fields) => {
172                    //// Expands to an expression like
173                    ////
174                    ////     0 + self.x.heap_size() + self.y.heap_size() + self.z.heap_size()
175                    ////
176                    //// but using fully qualified function call syntax.
177                    ////
178                    //// We take some care to use the span of each `syn::Field` as
179                    //// the span of the corresponding `heap_size_of_children`
180                    //// call. This way if one of the field types does not
181                    //// implement `HeapSize` then the compiler's error message
182                    //// underlines which field it is. An example is shown in the
183                    //// readme of the parent directory.
184                    //let recurse = fields.named.iter().map(|f| {
185                        //let name = &f.ident;
186                        //quote_spanned! {f.span()=>
187                            //heapsize::HeapSize::heap_size_of_children(&self.#name)
188                        //}
189                    //});
190                    //quote! {
191                        //0 #(+ #recurse)*
192                    //}
193                //}
194                //Fields::Unnamed(ref fields) => {
195                    //// Expands to an expression like
196                    ////
197                    ////     0 + self.0.heap_size() + self.1.heap_size() + self.2.heap_size()
198                    //let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
199                        //let index = Index::from(i);
200                        //quote_spanned! {f.span()=>
201                            //heapsize::HeapSize::heap_size_of_children(&self.#index)
202                        //}
203                    //});
204                    //quote! {
205                        //0 #(+ #recurse)*
206                    //}
207                //}
208                //Fields::Unit => {
209                    //// Unit structs cannot own more than 0 bytes of heap memory.
210                    //quote!(0)
211                //}
212            //}
213        //}
214        //Data::Enum(_) | Data::Union(_) => unimplemented!(),
215    //}
216//}