1use num_traits::Bounded;
2use std::{
3 fmt::{Display, Formatter, Result as FmtResult},
4 str::FromStr,
5};
6
7#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
9pub struct Min<T> {
10 value: Option<T>,
11}
12
13impl<T> Min<T>
14where
15 T: Copy + Ord,
16{
17 pub fn new() -> Self {
19 Self::default()
20 }
21
22 pub fn with_initial(initial: T) -> Self {
24 Self {
25 value: Some(initial),
26 }
27 }
28
29 pub fn get_min(&self) -> Option<T> {
34 self.value
35 }
36
37 pub fn get_min_extreme(&self) -> T
41 where
42 T: Bounded,
43 {
44 self.get_min().unwrap_or_else(T::max_value)
45 }
46
47 pub fn update<V: Into<Self>>(&mut self, value: V) {
52 match (self.value, value.into().value) {
53 (None, None) => self.value = None,
54 (Some(v), None) | (None, Some(v)) => self.value = Some(v),
55 (Some(v1), Some(v2)) => self.value = Some(v1.min(v2)),
56 }
57 }
58}
59
60impl<T> Default for Min<T> {
61 fn default() -> Self {
62 Self { value: None }
63 }
64}
65
66impl<T> From<T> for Min<T>
67where
68 T: Copy + Ord,
69{
70 fn from(value: T) -> Self {
71 Self::with_initial(value)
72 }
73}
74
75impl<T> FromIterator<T> for Min<T>
76where
77 T: Ord,
78{
79 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
80 let m = iter.into_iter().min();
81 if m.is_some() {
82 Self { value: m }
83 } else {
84 Self::default()
85 }
86 }
87}
88
89impl<T> Display for Min<T>
90where
91 T: Display,
92{
93 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
94 if let Some(v) = &self.value {
95 write!(f, "{}", v)
96 } else {
97 write!(f, "<uninitialized>")
98 }
99 }
100}
101
102impl<T> FromStr for Min<T>
103where
104 T: Copy + FromStr + Ord,
105{
106 type Err = T::Err;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
109 Ok(Self::with_initial(T::from_str(s)?))
110 }
111}
112
113#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
115pub struct Max<T> {
116 value: Option<T>,
117}
118
119impl<T> Max<T>
120where
121 T: Copy + Ord,
122{
123 pub fn new() -> Self {
125 Self::default()
126 }
127
128 pub fn with_initial(initial: T) -> Self {
130 Self {
131 value: Some(initial),
132 }
133 }
134
135 pub fn get_max(&self) -> Option<T> {
140 self.value
141 }
142
143 pub fn get_max_extreme(&self) -> T
147 where
148 T: Bounded,
149 {
150 self.get_max().unwrap_or_else(T::min_value)
151 }
152
153 pub fn update<V: Into<Self>>(&mut self, value: V) {
158 match (self.value, value.into().value) {
159 (None, None) => self.value = None,
160 (Some(v), None) | (None, Some(v)) => self.value = Some(v),
161 (Some(v1), Some(v2)) => self.value = Some(v1.max(v2)),
162 }
163 }
164}
165
166impl<T> Default for Max<T> {
167 fn default() -> Self {
168 Self { value: None }
169 }
170}
171
172impl<T> From<T> for Max<T>
173where
174 T: Copy + Ord,
175{
176 fn from(value: T) -> Self {
177 Self::with_initial(value)
178 }
179}
180
181impl<T> FromIterator<T> for Max<T>
182where
183 T: Ord,
184{
185 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
186 let m = iter.into_iter().max();
187 if m.is_some() {
188 Self { value: m }
189 } else {
190 Self::default()
191 }
192 }
193}
194
195impl<T> Display for Max<T>
196where
197 T: Display,
198{
199 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
200 if let Some(v) = &self.value {
201 write!(f, "{}", v)
202 } else {
203 write!(f, "<uninitialized>")
204 }
205 }
206}
207
208impl<T> FromStr for Max<T>
209where
210 T: Copy + FromStr + Ord,
211{
212 type Err = T::Err;
213
214 fn from_str(s: &str) -> Result<Self, Self::Err> {
215 Ok(Self::with_initial(T::from_str(s)?))
216 }
217}