From: Ian Jackson Date: Sat, 1 Feb 2025 12:14:48 +0000 (+0000) Subject: config: Replace use of Default with Parseable::Unspecified X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=cc839998967334ba28eaefd823d2a163a30f9031;p=hippotat.git config: Replace use of Default with Parseable::Unspecified Signed-off-by: Ian Jackson --- diff --git a/src/config.rs b/src/config.rs index 4d31309..aa76686 100644 --- a/src/config.rs +++ b/src/config.rs @@ -240,7 +240,8 @@ impl Parseable for Secret { Secret(s.into()) } #[throws(AE)] - fn default_for_ordinary() -> Self { Secret(default()) } + fn default_for_ordinary() -> Self { Parseable::unspecified() } + fn unspecified() -> Self { Secret(default()) } } impl Debug for Secret { #[throws(fmt::Error)] @@ -621,6 +622,20 @@ trait Parseable: Sized { fn default_for_ordinary() -> Result { Err(anyhow!("setting must be specified")) } + + /// Placeholder (infalliable) + /// + /// Used (sometimes) for lookups with + /// [`ResolveContest::client`], + /// [`server`](`ResolveContest::server`) and + /// [`computed`](`ResolveContest::server`). + /// + /// Ie, when the value need not be specified because + /// it may not be applicable, or could be computed. + /// + /// We could use `Default::default` but + /// not all the types we want to use implement that. + fn unspecified() -> Self; } impl Parseable for Duration { @@ -629,12 +644,15 @@ impl Parseable for Duration { // todo: would be nice to parse with humantime maybe Duration::from_secs( s.value()?.parse()? ) } + fn unspecified() -> Duration { Duration::ZERO } } macro_rules! parseable_from_str { ($t:ty, $def:expr) => { impl Parseable for $t { #[throws(AE)] fn parse(s: Option<&str>) -> $t { s.value()?.parse()? } - #[throws(AE)] fn default_for_ordinary() -> Self { $def } + #[throws(AE)] + fn default_for_ordinary() -> Self { Parseable::unspecified() } + fn unspecified() -> Self { $def } } } } parseable_from_str!{u16, default() } @@ -653,7 +671,8 @@ impl Parseable for Vec { .collect::,_>>()? } #[throws(AE)] - fn default_for_ordinary() -> Self { default() } + fn default_for_ordinary() -> Self { Parseable::unspecified() } + fn unspecified() -> Self { default() } } @@ -781,27 +800,27 @@ impl<'c> ResolveContext<'c> { #[throws(AE)] pub fn client(&self, key: &'static str, skl: SKL) -> T - where T: Parseable + Default { + where T: Parseable { match self.end { LinkEnd::Client => self.ordinary(key, skl)?, - LinkEnd::Server => default(), + LinkEnd::Server => Parseable::unspecified(), } } #[throws(AE)] pub fn server(&self, key: &'static str, skl: SKL) -> T - where T: Parseable + Default { + where T: Parseable { match self.end { LinkEnd::Server => self.ordinary(key, skl)?, - LinkEnd::Client => default(), + LinkEnd::Client => Parseable::unspecified(), } } #[throws(AE)] pub fn computed(&self, _key: &'static str, skl: SKL) -> T - where T: Default + where T: Parseable { assert_eq!(skl, SKL::None); - default() + Parseable::unspecified() } #[throws(AE)] @@ -861,7 +880,7 @@ impl InstanceConfig { match end { LinkEnd::Client => { - if self.url == default::() { + if self.url == Uri::unspecified() { let addr = self.addrs.get(0).ok_or_else( || anyhow!("client needs addrs or url set") )?;