Parse a duration like `30d`, `12h`, `90m`, or a bare number of days.
(raw: &str)
| 182 | |
| 183 | /// Parse a duration like `30d`, `12h`, `90m`, or a bare number of days. |
| 184 | pub fn parse_duration(raw: &str) -> CliResult<Duration> { |
| 185 | let raw = raw.trim(); |
| 186 | let invalid = || CliError::InvalidArgument { |
| 187 | message: format!( |
| 188 | "--expires: '{raw}' is not a duration (try 30d, 12h, 90m, or a number of days)" |
| 189 | ), |
| 190 | }; |
| 191 | |
| 192 | let (value, unit) = match raw.chars().last() { |
| 193 | Some(c) if c.is_ascii_alphabetic() => (&raw[..raw.len() - 1], c), |
| 194 | Some(_) => (raw, 'd'), |
| 195 | None => return Err(invalid()), |
| 196 | }; |
| 197 | |
| 198 | let value: i64 = value.trim().parse().map_err(|_| invalid())?; |
| 199 | if value <= 0 { |
| 200 | return Err(CliError::InvalidArgument { |
| 201 | message: "--expires must be a positive duration; a delegation that is already \ |
| 202 | expired would authorize nothing" |
| 203 | .to_string(), |
| 204 | }); |
| 205 | } |
| 206 | |
| 207 | match unit.to_ascii_lowercase() { |
| 208 | 'd' => Ok(Duration::days(value)), |
| 209 | 'h' => Ok(Duration::hours(value)), |
| 210 | 'm' => Ok(Duration::minutes(value)), |
| 211 | 'w' => Ok(Duration::weeks(value)), |
| 212 | _ => Err(invalid()), |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | /// The `urn:atomic:agent:<slug>` label for a software agent. |
| 217 | /// |