servo_config_macro/
lib.rs1use proc_macro2::TokenStream;
6use quote::quote;
7use syn::{Data, Fields};
8use synstructure::decl_derive;
9
10decl_derive!([ServoPreferences] => servo_preferences_derive);
11
12fn servo_preferences_derive(input: synstructure::Structure) -> TokenStream {
16 let ast = input.ast();
17
18 let Data::Struct(ref data) = ast.data else {
19 unimplemented!();
20 };
21 let Fields::Named(ref named_fields) = data.fields else {
22 unimplemented!()
23 };
24
25 let mut get_match_cases = quote!();
26 for field in named_fields.named.iter() {
27 let name = field.ident.as_ref().unwrap();
28 get_match_cases.extend(quote!(stringify!(#name) => self.#name.clone().into(),))
29 }
30
31 let mut set_match_cases = quote!();
32 for field in named_fields.named.iter() {
33 let name = field.ident.as_ref().unwrap();
34 set_match_cases.extend(quote!(stringify!(#name) => self.#name = value.try_into().unwrap(),))
35 }
36
37 let mut comparisons = quote!();
38 for field in named_fields.named.iter() {
39 let name = field.ident.as_ref().unwrap();
40 comparisons.extend(quote!(if self.#name != other.#name { changes.push((stringify!(#name), self.#name.clone().into(),)) }))
41 }
42
43 let structure_name = &ast.ident;
44 quote! {
45 impl #structure_name {
46 pub fn get_value(&self, name: &str) -> PrefValue {
47 match name {
48 #get_match_cases
49 _ => { panic!("Unknown preference: {:?}", name); }
50 }
51 }
52
53 pub fn set_value(&mut self, name: &str, value: PrefValue) {
54 match name {
55 #set_match_cases
56 _ => { panic!("Unknown preference: {:?}", name); }
57 }
58 }
59
60 pub fn diff(&self, other: &Self) -> Vec<(&'static str, PrefValue)> {
61 let mut changes = vec![];
62 #comparisons
63 changes
64 }
65 }
66 }
67}