// 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);
)
.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 ),* ];
#[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>,
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)]
}
}
+/*
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() {