chiark / gitweb /
config: get global config
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 21:47:50 +0000 (22:47 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 21:50:07 +0000 (22:50 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
macros/macros.rs
src/config.rs

index 56b17cd84b9c376b026d52d22b66e817c7278a3a..ee79e075ef7d71ba64508f1625538d8efac4a538 100644 (file)
@@ -67,16 +67,17 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     } => (f, ident),
     _ => panic!(),
   };
-dbg!(&top_ident);
 
   let target = &input.ident;
 
   let mut names = vec![];
   let mut output = vec![];
   let mut global_fields = vec![];
+  let mut global_assignments = vec![];
   for field in &fields.named {
     //dbg!(field);
     let fname = &field.ident.as_ref().unwrap();
+    let ty = &field.ty;
     let fname_span = fname.span();
     let skl = RefCell::new(None);
     let set_skl = |new| {
@@ -98,6 +99,10 @@ dbg!(&top_ident);
             attrs: vec![],
             ..field.clone()
           });
+          global_assignments.push(quote_spanned!(fname_span=>
+            #fname: <#ty as ResolveGlobal>::resolve
+                    (l.iter().map(|e| &e.#fname)),
+          ));
           continue;
         }
         method = attr.path.to_token_stream();
@@ -140,7 +145,7 @@ dbg!(&top_ident);
   }
   //dbg!(&output);
 
-  let global = syn::Ident::new(&format!("{}Common", top_ident),
+  let global = syn::Ident::new(&format!("{}Global", top_ident),
                                top_ident.span());
 
   let output = quote! {
@@ -161,6 +166,12 @@ dbg!(&top_ident);
     pub struct #global {
       #( #global_fields ),*
     }
+
+    impl #global {
+      pub fn from(l: &[#top_ident]) -> #global { #global {
+        #( #global_assignments )*
+      } }
+    }
   };
 
   //eprintln!("{}", &output);
index 98e5a1e940f2182cf6bd9f1501f3e450c2eacb71..048a91c88a8bd4994628c7bcf1b9b7838cc5bcb4 100644 (file)
@@ -814,6 +814,20 @@ impl InstanceConfig {
   }
 }
 
+trait ResolveGlobal<'i> where Self: 'i {
+  fn resolve<I>(it: I) -> Self
+  where I: Iterator<Item=&'i Self>;
+}
+impl<'i,T> ResolveGlobal<'i> for T where T: Eq + Clone + Debug + 'i {
+  fn resolve<I>(mut it: I) -> Self
+  where I: Iterator<Item=&'i Self>
+  {
+    let first = it.next().expect("empty instances no global!");
+    for x in it { assert_eq!(x, first); }
+    first.clone()
+  }
+}
+
 #[throws(AE)]
 pub fn read(opts: &Opts, end: LinkEnd) -> Vec<InstanceConfig> {
   let agg = (||{