From 70380d052ca31af50fdb4a38f8be6e834a8818da Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 24 Jul 2021 13:49:10 +0100 Subject: [PATCH] config, centralise "value needed" Signed-off-by: Ian Jackson --- src/config.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/config.rs b/src/config.rs index 75c3e25..3eae89d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -21,11 +21,19 @@ pub struct Opts { pub extra_config: Vec, } +#[ext] +impl<'s> Option<&'s str> { + #[throws(AE)] + fn value(self) -> &'s str { + self.ok_or_else(|| anyhow!("value needed"))? + } +} + pub struct Secret(pub String); impl Parseable for Secret { #[throws(AE)] fn parse(s: Option<&str>) -> Self { - let s = s.ok_or_else(|| anyhow!("value needed"))?; + let s = s.value()?; if s.is_empty() { throw!(anyhow!("secret value cannot be empty")) } Secret(s.into()) } @@ -294,7 +302,7 @@ trait Parseable: Sized { impl Parseable for Duration { #[throws(AE)] fn parse(s: Option<&str>) -> Duration { - let s = s.as_ref().ok_or_else(|| anyhow!("value needed"))?; + let s = s.value()?; if let Ok(u64) = s.parse() { return Duration::from_secs(u64) } throw!(anyhow!("xxx parse with humantime")) } @@ -302,13 +310,8 @@ impl Parseable for Duration { macro_rules! parseable_from_str { ($t:ty $(, $def:expr)? ) => { impl Parseable for $t { #[throws(AE)] - fn parse(s: Option<&str>) -> $t { - let s = s.as_ref().ok_or_else(|| anyhow!("value needed"))?; - s.parse()? - } - $( - #[throws(AE)] fn default() -> Self { $def } - )? + fn parse(s: Option<&str>) -> $t { s.value()?.parse()? } + $( #[throws(AE)] fn default() -> Self { $def } )? } } } parseable_from_str!{u16, default() } @@ -321,8 +324,8 @@ parseable_from_str!{Uri, default() } impl Parseable for Vec { #[throws(AE)] fn parse(s: Option<&str>) -> Vec { - let s = s.as_ref().ok_or_else(|| anyhow!("value needed"))?; - s.split_ascii_whitespace() + s.value()? + .split_ascii_whitespace() .map(|s| Parseable::parse(Some(s))) .collect::,_>>()? } @@ -466,8 +469,7 @@ impl<'c> ResolveContext<'c> { "server", [ &SectionName::Common, &self.special_server_section ].iter().cloned() ) { - Some(RawVal { val: Some(ref got),.. }) => got, - Some(RawVal { val: None,.. }) => throw!(anyhow!("value needed")), + Some(raw) => raw.val.as_deref().value()?, None => SPECIAL_SERVER_SECTION, }; ServerName(raw.into()) -- 2.30.2