chiark / gitweb /
config: Replace use of Default with Parseable::Unspecified
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 1 Feb 2025 12:14:48 +0000 (12:14 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 1 Feb 2025 12:37:23 +0000 (12:37 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/config.rs

index 4d31309970f9695f33678b2ed65f88e4973857a9..aa76686dc960f8b060e0bea5bdde57393d5f50ec 100644 (file)
@@ -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<Self, AE> {
     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<T:Parseable> Parseable for Vec<T> {
       .collect::<Result<Vec<_>,_>>()?
   }
   #[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<T>(&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<T>(&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<T>(&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::<Uri>() {
+        if self.url == Uri::unspecified() {
           let addr = self.addrs.get(0).ok_or_else(
             || anyhow!("client needs addrs or url set")
           )?;