asimov_patterns/options/
caching.rs1#[cfg(feature = "clap")]
6use alloc::string::ToString;
7#[cfg(any(feature = "std", feature = "clap"))]
8use alloc::{format, string::String};
9use bon::Builder;
10use core::time::Duration;
11
12#[cfg(feature = "clap")]
13const HELP_MAX_AGE: &str = r#"Maximum acceptable cache age.
14
15Use a positive duration such as 1h, 7d, or "1m 30s".
16If omitted, the default is module-specific."#;
17
18#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Builder)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35#[builder(derive(Debug))]
36#[cfg_attr(feature = "clap", derive(clap::Args))]
37#[cfg_attr(feature = "clap", command(about = None, long_about = None))]
38pub struct CachingOptions {
39 #[cfg_attr(
42 feature = "clap",
43 clap(
44 long,
45 value_name = "DURATION",
46 value_parser = parse_max_age,
47 help = "Maximum acceptable cache age",
48 long_help = HELP_MAX_AGE
49 )
50 )]
51 #[cfg_attr(
52 feature = "serde",
53 serde(
54 rename = "max-age",
55 alias = "max_age",
56 alias = "maxAge",
57 default,
58 skip_serializing_if = "Option::is_none",
59 with = "crate::serialization::optional_duration"
60 )
61 )]
62 pub max_age: Option<Duration>,
63}
64
65#[cfg(any(feature = "std", feature = "clap"))]
66impl CachingOptions {
67 pub fn max_age_option(&self) -> Option<String> {
71 self.max_age
72 .map(|value| format!("--max-age={}", humantime::format_duration(value)))
73 }
74}
75
76#[cfg(feature = "clap")]
77fn parse_max_age(value: &str) -> Result<Duration, String> {
78 let duration = humantime::parse_duration(value).map_err(|error| error.to_string())?;
79 if duration.is_zero() {
80 return Err("max age must be positive".into());
81 }
82 Ok(duration)
83}