From: Ian Jackson Date: Sat, 7 Aug 2021 16:57:36 +0000 (+0100) Subject: config: Pass SKL to all the method functions, and document semantics X-Git-Tag: hippotat/1.0.0~274 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=7ef18168bed6e6139815280a41891a3d9f91132f;p=hippotat.git config: Pass SKL to all the method functions, and document semantics This will make it possible to use the same method for things with different applicable sections. Signed-off-by: Ian Jackson --- diff --git a/macros/macros.rs b/macros/macros.rs index ac1a497..64501be 100644 --- a/macros/macros.rs +++ b/macros/macros.rs @@ -11,6 +11,12 @@ use itertools::Itertools; /// Generates config resolver method /// +/// Each field ends up having an SKL and a method. +/// The method actually looks up the value in a particular link context. +/// SKL is passed to the method, which usually uses it to decide which +/// sections to look in. But it is also used by general validation, +/// unconditionally, to reject settings in the wrong section. +/// /// Atrributes: /// /// * `limited`, `server`, `client`: cooked sets of settings; @@ -22,13 +28,16 @@ use itertools::Itertools; /// ```no_run /// impl<'c> ResolveContext<'c> { /// +/// // SKL here is used by SectionKindList::contains() /// const FIELDS: &'static [(&'static str, SectionKindList)] = &[ ... ]; /// /// #[throws(AE)] /// fn resolve_instance(&self) -> InstanceConfig { /// InstanceConfig { /// ... -/// max_batch_down: self.limited("max_batch_down")?, +/// // SKL here is usually passed to first_of, but the method +/// // can do something more special. +/// max_batch_down: self.limited("max_batch_down", SKL::PerClient)?, /// ... /// } /// } @@ -86,7 +95,7 @@ pub fn resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream { }); //dbg!(&method); output.push(quote!{ - #fname: rctx. #method ( #fname_lit )?, + #fname: rctx. #method ( #fname_lit, #skl )?, }); //eprintln!("{:?} method={:?} skl={:?}", field.ident, method, skl); } diff --git a/src/config.rs b/src/config.rs index a364efc..6a5e6bf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -610,20 +610,21 @@ impl<'c> ResolveContext<'c> { } #[throws(AE)] - pub fn ordinary(&self, key: &'static str) -> T + pub fn ordinary(&self, key: &'static str, skl: SKL) -> T where T: Parseable { - match self.first_of(key, SKL::PerClient)? { + match self.first_of(key, skl)? { Some(y) => y, None => Parseable::default_for_key(key)?, } } #[throws(AE)] - pub fn limited(&self, key: &'static str) -> T + pub fn limited(&self, key: &'static str, skl: SKL) -> T where T: Parseable + Ord { - let val = self.ordinary(key)?; + assert_eq!(skl, SKL::Limited); + let val = self.ordinary(key, SKL::PerClient)?; if let Some(limit) = self.first_of(key, SKL::Limits)? { min(val, limit) } else { @@ -632,33 +633,34 @@ impl<'c> ResolveContext<'c> { } #[throws(AE)] - pub fn client(&self, key: &'static str) -> T + pub fn client(&self, key: &'static str, skl: SKL) -> T where T: Parseable + Default { match self.end { - LinkEnd::Client => self.ordinary(key)?, + LinkEnd::Client => self.ordinary(key, skl)?, LinkEnd::Server => default(), } } #[throws(AE)] - pub fn server(&self, key: &'static str) -> T + pub fn server(&self, key: &'static str, skl: SKL) -> T where T: Parseable + Default { match self.end { - LinkEnd::Server => self.ordinary(key)?, + LinkEnd::Server => self.ordinary(key, skl)?, LinkEnd::Client => default(), } } #[throws(AE)] - pub fn computed(&self, _key: &'static str) -> T + pub fn computed(&self, _key: &'static str, _skl: SKL) -> T where T: Default { default() } #[throws(AE)] - pub fn special_ipif(&self, key: &'static str) -> String { + pub fn special_ipif(&self, key: &'static str, skl: SKL) -> String { + assert_eq!(skl, SKL::PerClient); // we tolerate it in per-client sections match self.end { - LinkEnd::Client => self.ordinary(key)?, + LinkEnd::Client => self.ordinary(key, SKL::PerClient)?, LinkEnd::Server => { self.first_of(key, SKL::Global)? .unwrap_or_default() @@ -667,7 +669,7 @@ impl<'c> ResolveContext<'c> { } #[throws(AE)] - pub fn special_link(&self, _key: &'static str) -> LinkName { + pub fn special_link(&self, _key: &'static str, _skl: SKL) -> LinkName { self.link.clone() } }