1use crate::{DurationError, DurationHuman};
2
3#[derive(Default)]
4pub struct DurationHumanValidator {
5 pub min: DurationHuman,
6 pub default: DurationHuman,
7 pub max: DurationHuman,
8}
9
10impl DurationHumanValidator {
11 #[must_use]
16 pub const fn new(minimal_nanos: u64, default_nanos: u64, maximal_nanos: u64) -> Self {
17 assert!(minimal_nanos <= default_nanos && default_nanos <= maximal_nanos);
18 assert!(minimal_nanos >= DurationHuman::SEC);
19 assert!(default_nanos >= DurationHuman::SEC);
20 assert!(maximal_nanos >= DurationHuman::SEC);
21
22 Self {
23 min: DurationHuman::new(minimal_nanos),
24 default: DurationHuman::new(default_nanos),
25 max: DurationHuman::new(maximal_nanos),
26 }
27 }
28
29 const fn try_new(
30 minimal_nanos: u64,
31 default_nanos: u64,
32 maximal_nanos: u64,
33 ) -> Result<Self, DurationError> {
34 if minimal_nanos < DurationHuman::SEC {
35 Err(DurationError::DurationValidationMinMustBeMoreThanOneSecond)
36 } else if default_nanos < DurationHuman::SEC {
37 Err(DurationError::DurationValidationDefaultMustBeMoreThanOneSecond)
38 } else {
39 Ok(Self {
40 min: DurationHuman::new(minimal_nanos),
41 default: DurationHuman::new(default_nanos),
42 max: DurationHuman::new(maximal_nanos),
43 })
44 }
45 }
46
47 pub fn parse_and_validate(&self, duration: &str) -> Result<DurationHuman, DurationError> {
57 let duration_in_nanos = DurationHuman::try_from(duration)?;
58
59 if self.contains(&duration_in_nanos) {
60 Ok(duration_in_nanos)
61 } else {
62 Err(DurationError::DurationMustLieBetween {
63 range: self.to_string(),
64 })
65 }
66 }
67
68 #[must_use]
69 pub fn contains(&self, duration: &DurationHuman) -> bool {
70 self.min <= *duration && *duration <= self.max
71 }
72}
73
74impl From<&DurationHumanValidator> for (u64, u64, u64) {
75 fn from(duration: &DurationHumanValidator) -> Self {
76 (
77 (&duration.min).into(),
78 (&duration.default).into(),
79 (&duration.max).into(),
80 )
81 }
82}
83
84impl From<&DurationHumanValidator> for (String, String, String) {
85 fn from(duration: &DurationHumanValidator) -> Self {
86 (
87 duration.min.to_string(),
88 duration.default.to_string(),
89 duration.max.to_string(),
90 )
91 }
92}
93
94impl TryFrom<(DurationHuman, DurationHuman)> for DurationHumanValidator {
95 type Error = DurationError;
96
97 fn try_from(value: (DurationHuman, DurationHuman)) -> Result<Self, Self::Error> {
98 let (minimal, maximal) = &value;
99 if minimal > maximal {
100 Err(DurationError::DurationValidationMinMustBeLessOrEqualMax {
101 minimal: minimal.to_string(),
102 maximal: maximal.to_string(),
103 })
104 } else {
105 let (minimal_ms, maximal_ms): (u64, u64) = (minimal.into(), maximal.into());
106 Self::try_new(minimal_ms, minimal_ms, maximal_ms)
107 }
108 }
109}
110
111impl TryFrom<(DurationHuman, DurationHuman, DurationHuman)> for DurationHumanValidator {
112 type Error = DurationError;
113
114 fn try_from(value: (DurationHuman, DurationHuman, DurationHuman)) -> Result<Self, Self::Error> {
115 let (minimal, default, maximal) = &value;
116 if minimal > default || maximal < default {
117 Err(DurationError::DurationValidationMustBeOrdered {
118 minimal: minimal.to_string(),
119 default: default.to_string(),
120 maximal: maximal.to_string(),
121 })
122 } else {
123 let (minimal_ms, default_ms, maximal_ms): (u64, u64, u64) =
124 (minimal.into(), default.into(), maximal.into());
125 Self::try_new(minimal_ms, default_ms, maximal_ms)
126 }
127 }
128}
129
130impl TryFrom<(u64, u64, u64)> for DurationHumanValidator {
131 type Error = DurationError;
132
133 fn try_from(value: (u64, u64, u64)) -> Result<Self, Self::Error> {
134 let min_def_max: (DurationHuman, DurationHuman, DurationHuman) = (
135 (DurationHuman::from(value.0)),
136 (DurationHuman::from(value.1)),
137 (DurationHuman::from(value.2)),
138 );
139 Self::try_from(min_def_max)
140 }
141}
142
143impl TryFrom<(&str, &str, &str)> for DurationHumanValidator {
144 type Error = DurationError;
145
146 fn try_from(value: (&str, &str, &str)) -> Result<Self, Self::Error> {
147 let min_def_max: (DurationHuman, DurationHuman, DurationHuman) = (
148 (DurationHuman::try_from(value.0)?),
149 (DurationHuman::try_from(value.1)?),
150 (DurationHuman::try_from(value.2)?),
151 );
152
153 Self::try_from(min_def_max)
154 }
155}
156
157impl TryFrom<(u64, u64)> for DurationHumanValidator {
158 type Error = DurationError;
159
160 fn try_from(value: (u64, u64)) -> Result<Self, Self::Error> {
161 let min_max: (DurationHuman, DurationHuman) = (
162 (DurationHuman::from(value.0)),
163 (DurationHuman::from(value.1)),
164 );
165 Self::try_from(min_max)
166 }
167}
168
169impl TryFrom<(&str, &str)> for DurationHumanValidator {
170 type Error = DurationError;
171
172 fn try_from(value: (&str, &str)) -> Result<Self, Self::Error> {
173 let min_max: (DurationHuman, DurationHuman) = (
174 (DurationHuman::try_from(value.0)?),
175 (DurationHuman::try_from(value.1)?),
176 );
177
178 Self::try_from(min_max)
179 }
180}