compose_lens/model/
lifecycle.rs1#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum StopGracePeriod {
6 Value(String),
8 Expression(String),
10 Other(String),
12}
13
14impl StopGracePeriod {
15 pub(crate) fn parse(value: String) -> Self {
16 if value.contains('$') {
17 Self::Expression(value)
18 } else if valid_stop_grace_period(&value) {
19 Self::Value(value)
20 } else {
21 Self::Other(value)
22 }
23 }
24
25 #[must_use]
27 pub const fn is_valid(&self) -> bool {
28 !matches!(self, Self::Other(_))
29 }
30
31 #[must_use]
33 pub fn raw(&self) -> &str {
34 match self {
35 Self::Value(value) | Self::Expression(value) | Self::Other(value) => value,
36 }
37 }
38}
39
40pub(crate) fn valid_stop_grace_period(mut value: &str) -> bool {
41 let mut found = false;
42 while !value.is_empty() {
43 let number_end = value
44 .char_indices()
45 .take_while(|(_, character)| character.is_ascii_digit() || *character == '.')
46 .map(|(index, character)| index + character.len_utf8())
47 .last()
48 .unwrap_or(0);
49 if number_end == 0 {
50 return false;
51 }
52 let number = &value[..number_end];
53 if number.matches('.').count() > 1 || number == "." || number.ends_with('.') {
54 return false;
55 }
56 value = &value[number_end..];
57 let Some(unit) = ["us", "ms", "s", "m", "h"]
58 .into_iter()
59 .find(|unit| value.starts_with(unit))
60 else {
61 return false;
62 };
63 value = &value[unit.len()..];
64 found = true;
65 }
66 found
67}
68
69#[cfg(test)]
70mod tests {
71 use super::{StopGracePeriod, valid_stop_grace_period};
72
73 #[test]
74 fn applies_the_raw_preserving_policy_using_documented_compose_units() {
75 for value in ["1us", "1ms", "1s", "1m", "1h", "1m30s", "0s", "1.5s", ".5s"] {
76 assert!(valid_stop_grace_period(value), "expected valid duration {value}");
77 }
78 for value in ["", "0", "1", "1ns", "1µs", "1μs", "1d", "s", ".s", "1.s", "1..5s"] {
79 assert!(!valid_stop_grace_period(value), "expected invalid duration {value}");
80 }
81 }
82
83 #[test]
84 fn retains_valid_expression_and_other_spelling() {
85 assert_eq!(
86 StopGracePeriod::parse("1m30s".to_owned()),
87 StopGracePeriod::Value("1m30s".to_owned())
88 );
89 assert_eq!(
90 StopGracePeriod::parse("${STOP_GRACE_PERIOD:-1s}".to_owned()),
91 StopGracePeriod::Expression("${STOP_GRACE_PERIOD:-1s}".to_owned())
92 );
93 assert_eq!(
94 StopGracePeriod::parse("1ns".to_owned()),
95 StopGracePeriod::Other("1ns".to_owned())
96 );
97 }
98
99 #[test]
100 fn uses_the_existing_dollar_marker_as_a_lexical_expression_classification() {
101 assert_eq!(
102 StopGracePeriod::parse("literal$5".to_owned()),
103 StopGracePeriod::Expression("literal$5".to_owned())
104 );
105 }
106}