chiark / gitweb /
config, wip macro
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 11:04:14 +0000 (12:04 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 11:04:14 +0000 (12:04 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
macros/macros.rs
src/config.rs

index be1dee1c75a86975111d698e9dfb79a7382eac25..a3741bf235ae3cc869f35f1db8dea76bc168b187 100644 (file)
@@ -3,14 +3,22 @@
 // There is NO WARRANTY.
 
 #![allow(unused_imports)] // xxx
+#![allow(unused_variables)] // xxx
+#![allow(unused_mut)] // xxx
 
-use syn::{parse_macro_input, Data, DataStruct, DeriveInput};
+use syn::{parse_macro_input, parse_quote, Data, DataStruct, DeriveInput, Meta, NestedMeta, Path};
 use quote::{quote, quote_spanned};
-use proc_macro2::Literal;
+use proc_macro2::{Literal, TokenStream};
 
 use itertools::Itertools;
 
-#[proc_macro_derive(ResolveConfig, attributes(is, via))]
+/// Atrributes:
+///
+///  * `limited`, `server`, `client`: cooked sets of settings
+///  * `special(method, SKL)`
+#[proc_macro_derive(ResolveConfig, attributes(
+  limited, server, client, special
+))]
 pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
   let input = parse_macro_input!(input as DeriveInput);
 
@@ -25,6 +33,40 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
   )
     .collect_vec();
 
+//  let mut output = vec![];
+  for field in &fields.named {
+//    dbg!(field);
+    let mut skl = quote!{ SKL::Ordinary };
+    let mut method = quote!{ ordinary };
+    for attr in &field.attrs {
+      if attr.tokens.is_empty() {
+        if &attr.path == &parse_quote!{ limited } {
+          skl = quote!{ SKL::Limited };
+          method = quote!{ limited };
+        } else if &attr.path == &parse_quote!{ server } {
+          method = quote!{ server };
+        } else if &attr.path == &parse_quote!{ client } {
+          method = quote!{ client };
+        }
+      } else if &attr.path == &parse_quote!{ special } {
+        let meta = match attr.parse_meta().unwrap() {
+          Meta::List(list) => list,
+          _ => panic!(),
+        };
+        let (tmethod, tskl) = meta.nested.iter().collect_tuple().unwrap();
+        fn get_path(meta: &NestedMeta) -> TokenStream {
+          match meta {
+            NestedMeta::Meta(Meta::Path(ref path)) => quote!{ #path },
+            _ => panic!(),
+          }
+        }
+        method = get_path(tmethod);
+        skl    = get_path(tskl);
+      }
+    }
+    eprintln!("{:?} method={:?} skl={:?}", field.ident, method, skl);
+  }
+
   let output = quote! {
     impl #target {
       const FIELDS: &'static [&'static str] = &[ #( #names ),* ];
index e72f9981c13226723d10a41894ea20098445f9e8..93693b1c4c32cdc9f5251a4cb79bb0006773d41a 100644 (file)
@@ -25,18 +25,16 @@ pub struct CidrString(pub String);
 
 #[derive(hippotat_macros::ResolveConfig)]
 pub struct InstanceConfig {
-/*
   // Exceptional settings
-  pub server:                       String,
-  pub secret:                       String, // make a newytpe
-  pub ipif:                         String,
-*/
+  #[special(special_name, SKL::ServerName)] pub server: String,
+  pub                                           secret: String, // xxx newytpe
+  #[special(special_ipif, SKL::Ordinary)]   pub ipif:   String,
+
   // Capped settings:
-  pub max_batch_down:               u32,
-/*
-  pub max_queue_time:               Duration,
-  pub http_timeout:                 Duration,
-  pub target_requests_outstanding:  u32,
+  #[limited]    pub max_batch_down:               u32,
+  #[limited]    pub max_queue_time:               Duration,
+  #[limited]    pub http_timeout:                 Duration,
+  #[limited]    pub target_requests_outstanding:  u32,
 
   // Ordinary settings:
   pub addrs:                        Vec<IpAddr>,
@@ -49,16 +47,15 @@ pub struct InstanceConfig {
   pub ifname_client:                String,
 
   // Ordinary settings, used by server only:
-  pub max_clock_skew:               Duration,
+  #[server]  pub max_clock_skew:               Duration,
 
   // Ordinary settings, used by client only:
-  pub http_timeout_grace:           Duration,
-  pub max_requests_outstanding:     u32,
-  pub max_batch_up:                 u32,
-  pub http_retry:                   Duration,
-  pub url:                          Uri,
-  pub vroutes:                      Vec<CidrString>,
-*/
+  #[client]  pub http_timeout_grace:           Duration,
+  #[client]  pub max_requests_outstanding:     u32,
+  #[client]  pub max_batch_up:                 u32,
+  #[client]  pub http_retry:                   Duration,
+  #[client]  pub url:                          Uri,
+  #[client]  pub vroutes:                      Vec<CidrString>,
 }
 
 #[derive(Debug,Clone,Hash,Eq,PartialEq)]
@@ -407,14 +404,16 @@ impl<'c> ResolveContext<'c> {
   }
 }
 
+/*
 impl<'c> ResolveContext<'c> {
   #[throws(AE)]
   fn resolve_instance(&self) -> InstanceConfig {
     InstanceConfig {
-      max_batch_down: self.limited::<u32>("max_batch_down")?.into(),
+      max_batch_down: self.limited::<u32>("max_batch_down")?,
     }
   }
 }
+*/
 
 #[throws(AE)]
 pub fn read() {