/rust/registry/src/index.crates.io-6f17d22bba15001f/writeable-0.5.5/src/ops.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of ICU4X. For terms of use, please see the file |
2 | | // called LICENSE at the top level of the ICU4X source tree |
3 | | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
4 | | |
5 | | use crate::LengthHint; |
6 | | |
7 | | impl core::ops::Add<LengthHint> for LengthHint { |
8 | | type Output = Self; |
9 | | |
10 | 0 | fn add(self, other: LengthHint) -> Self { |
11 | 0 | LengthHint( |
12 | 0 | self.0.saturating_add(other.0), |
13 | 0 | match (self.1, other.1) { |
14 | 0 | (Some(c), Some(d)) => c.checked_add(d), |
15 | 0 | _ => None, |
16 | | }, |
17 | | ) |
18 | 0 | } |
19 | | } |
20 | | |
21 | | impl core::ops::AddAssign<LengthHint> for LengthHint { |
22 | 0 | fn add_assign(&mut self, other: Self) { |
23 | 0 | *self = *self + other; |
24 | 0 | } |
25 | | } |
26 | | |
27 | | impl core::iter::Sum<LengthHint> for LengthHint { |
28 | 0 | fn sum<I>(iter: I) -> Self |
29 | 0 | where |
30 | 0 | I: Iterator<Item = LengthHint>, |
31 | 0 | { |
32 | 0 | iter.fold(LengthHint::exact(0), core::ops::Add::add) |
33 | 0 | } |
34 | | } |
35 | | |
36 | | impl core::ops::Add<usize> for LengthHint { |
37 | | type Output = Self; |
38 | | |
39 | 0 | fn add(self, other: usize) -> Self { |
40 | 0 | Self( |
41 | 0 | self.0.saturating_add(other), |
42 | 0 | self.1.and_then(|upper| upper.checked_add(other)), |
43 | 0 | ) |
44 | 0 | } |
45 | | } |
46 | | |
47 | | impl core::ops::AddAssign<usize> for LengthHint { |
48 | 0 | fn add_assign(&mut self, other: usize) { |
49 | 0 | *self = *self + other; |
50 | 0 | } |
51 | | } |
52 | | |
53 | | impl core::ops::Mul<usize> for LengthHint { |
54 | | type Output = Self; |
55 | | |
56 | 0 | fn mul(self, other: usize) -> Self { |
57 | 0 | Self( |
58 | 0 | self.0.saturating_mul(other), |
59 | 0 | self.1.and_then(|upper| upper.checked_mul(other)), |
60 | 0 | ) |
61 | 0 | } |
62 | | } |
63 | | |
64 | | impl core::ops::MulAssign<usize> for LengthHint { |
65 | 0 | fn mul_assign(&mut self, other: usize) { |
66 | 0 | *self = *self * other; |
67 | 0 | } |
68 | | } |
69 | | |
70 | | impl core::ops::BitOr<LengthHint> for LengthHint { |
71 | | type Output = Self; |
72 | | |
73 | | /// Returns a new hint that is correct wherever `self` is correct, and wherever |
74 | | /// `other` is correct. |
75 | | /// |
76 | | /// Example: |
77 | | /// ``` |
78 | | /// # use writeable::{LengthHint, Writeable}; |
79 | | /// # use core::fmt; |
80 | | /// # fn coin_flip() -> bool { true } |
81 | | /// |
82 | | /// struct NonDeterministicWriteable(String, String); |
83 | | /// |
84 | | /// impl Writeable for NonDeterministicWriteable { |
85 | | /// fn write_to<W: fmt::Write + ?Sized>( |
86 | | /// &self, |
87 | | /// sink: &mut W, |
88 | | /// ) -> fmt::Result { |
89 | | /// sink.write_str(if coin_flip() { &self.0 } else { &self.1 }) |
90 | | /// } |
91 | | /// |
92 | | /// fn writeable_length_hint(&self) -> LengthHint { |
93 | | /// LengthHint::exact(self.0.len()) | LengthHint::exact(self.1.len()) |
94 | | /// } |
95 | | /// } |
96 | | /// |
97 | | /// writeable::impl_display_with_writeable!(NonDeterministicWriteable); |
98 | | /// ``` |
99 | 0 | fn bitor(self, other: LengthHint) -> Self { |
100 | 0 | LengthHint( |
101 | 0 | Ord::min(self.0, other.0), |
102 | 0 | match (self.1, other.1) { |
103 | 0 | (Some(c), Some(d)) => Some(Ord::max(c, d)), |
104 | 0 | _ => None, |
105 | | }, |
106 | | ) |
107 | 0 | } |
108 | | } |
109 | | |
110 | | impl core::ops::BitOrAssign<LengthHint> for LengthHint { |
111 | 0 | fn bitor_assign(&mut self, other: Self) { |
112 | 0 | *self = *self | other; |
113 | 0 | } |
114 | | } |
115 | | |
116 | | impl core::iter::Sum<usize> for LengthHint { |
117 | 0 | fn sum<I>(iter: I) -> Self |
118 | 0 | where |
119 | 0 | I: Iterator<Item = usize>, |
120 | 0 | { |
121 | 0 | LengthHint::exact(iter.sum::<usize>()) |
122 | 0 | } |
123 | | } |
124 | | |
125 | | #[cfg(test)] |
126 | | mod tests { |
127 | | use super::*; |
128 | | |
129 | | #[test] |
130 | | fn test_add() { |
131 | | assert_eq!(LengthHint::exact(3) + 2, LengthHint::exact(5)); |
132 | | assert_eq!( |
133 | | LengthHint::exact(3) + LengthHint::exact(2), |
134 | | LengthHint::exact(5) |
135 | | ); |
136 | | assert_eq!( |
137 | | LengthHint::exact(3) + LengthHint::undefined(), |
138 | | LengthHint::at_least(3) |
139 | | ); |
140 | | |
141 | | assert_eq!(LengthHint::undefined() + 2, LengthHint::at_least(2)); |
142 | | assert_eq!( |
143 | | LengthHint::undefined() + LengthHint::exact(2), |
144 | | LengthHint::at_least(2) |
145 | | ); |
146 | | assert_eq!( |
147 | | LengthHint::undefined() + LengthHint::undefined(), |
148 | | LengthHint::undefined() |
149 | | ); |
150 | | |
151 | | assert_eq!( |
152 | | LengthHint::at_least(15) + LengthHint::exact(3), |
153 | | LengthHint::at_least(18) |
154 | | ); |
155 | | |
156 | | assert_eq!( |
157 | | LengthHint::at_least(15) + LengthHint::at_most(3), |
158 | | LengthHint::at_least(15) |
159 | | ); |
160 | | |
161 | | assert_eq!(LengthHint::between(48, 92) + 5, LengthHint::between(53, 97)); |
162 | | |
163 | | let mut len = LengthHint::exact(5); |
164 | | len += LengthHint::exact(3); |
165 | | assert_eq!(len, LengthHint::exact(8)); |
166 | | len += 2; |
167 | | assert_eq!(len, LengthHint::exact(10)); |
168 | | len += LengthHint::undefined(); |
169 | | assert_eq!(len, LengthHint::at_least(10)); |
170 | | |
171 | | len += LengthHint::exact(3); |
172 | | assert_eq!(len, LengthHint::at_least(13)); |
173 | | len += 2; |
174 | | assert_eq!(len, LengthHint::at_least(15)); |
175 | | len += LengthHint::undefined(); |
176 | | assert_eq!(len, LengthHint::at_least(15)); |
177 | | |
178 | | assert_eq!( |
179 | | LengthHint::between(usize::MAX - 10, usize::MAX - 5) + LengthHint::exact(20), |
180 | | LengthHint::at_least(usize::MAX) |
181 | | ); |
182 | | } |
183 | | |
184 | | #[test] |
185 | | fn test_sum() { |
186 | | let lens = [ |
187 | | LengthHint::exact(4), |
188 | | LengthHint::exact(1), |
189 | | LengthHint::exact(1), |
190 | | ]; |
191 | | assert_eq!( |
192 | | lens.iter().copied().sum::<LengthHint>(), |
193 | | LengthHint::exact(6) |
194 | | ); |
195 | | |
196 | | let lens = [ |
197 | | LengthHint::exact(4), |
198 | | LengthHint::undefined(), |
199 | | LengthHint::at_least(1), |
200 | | ]; |
201 | | assert_eq!( |
202 | | lens.iter().copied().sum::<LengthHint>(), |
203 | | LengthHint::at_least(5) |
204 | | ); |
205 | | |
206 | | let lens = [ |
207 | | LengthHint::exact(4), |
208 | | LengthHint::undefined(), |
209 | | LengthHint::at_most(1), |
210 | | ]; |
211 | | assert_eq!( |
212 | | lens.iter().copied().sum::<LengthHint>(), |
213 | | LengthHint::at_least(4) |
214 | | ); |
215 | | |
216 | | let lens = [4, 1, 1]; |
217 | | assert_eq!( |
218 | | lens.iter().copied().sum::<LengthHint>(), |
219 | | LengthHint::exact(6) |
220 | | ); |
221 | | } |
222 | | |
223 | | #[test] |
224 | | fn test_mul() { |
225 | | assert_eq!(LengthHint::exact(3) * 2, LengthHint::exact(6)); |
226 | | |
227 | | assert_eq!(LengthHint::undefined() * 2, LengthHint::undefined()); |
228 | | |
229 | | assert_eq!( |
230 | | LengthHint::between(48, 92) * 2, |
231 | | LengthHint::between(96, 184) |
232 | | ); |
233 | | |
234 | | let mut len = LengthHint::exact(5); |
235 | | len *= 2; |
236 | | assert_eq!(len, LengthHint::exact(10)); |
237 | | |
238 | | assert_eq!( |
239 | | LengthHint::between(usize::MAX - 10, usize::MAX - 5) * 2, |
240 | | LengthHint::at_least(usize::MAX) |
241 | | ); |
242 | | } |
243 | | |
244 | | #[test] |
245 | | fn test_bitor() { |
246 | | assert_eq!( |
247 | | LengthHint::exact(3) | LengthHint::exact(2), |
248 | | LengthHint::between(2, 3) |
249 | | ); |
250 | | assert_eq!( |
251 | | LengthHint::exact(3) | LengthHint::undefined(), |
252 | | LengthHint::undefined() |
253 | | ); |
254 | | |
255 | | assert_eq!( |
256 | | LengthHint::undefined() | LengthHint::undefined(), |
257 | | LengthHint::undefined() |
258 | | ); |
259 | | |
260 | | assert_eq!( |
261 | | LengthHint::exact(10) | LengthHint::exact(10), |
262 | | LengthHint::exact(10) |
263 | | ); |
264 | | |
265 | | assert_eq!( |
266 | | LengthHint::at_least(15) | LengthHint::exact(3), |
267 | | LengthHint::at_least(3) |
268 | | ); |
269 | | |
270 | | assert_eq!( |
271 | | LengthHint::at_least(15) | LengthHint::at_most(18), |
272 | | LengthHint::undefined() |
273 | | ); |
274 | | |
275 | | assert_eq!( |
276 | | LengthHint::at_least(15) | LengthHint::at_least(18), |
277 | | LengthHint::at_least(15) |
278 | | ); |
279 | | |
280 | | assert_eq!( |
281 | | LengthHint::at_most(15) | LengthHint::at_most(18), |
282 | | LengthHint::at_most(18) |
283 | | ); |
284 | | |
285 | | assert_eq!( |
286 | | LengthHint::between(5, 10) | LengthHint::at_most(3), |
287 | | LengthHint::at_most(10) |
288 | | ); |
289 | | |
290 | | let mut len = LengthHint::exact(5); |
291 | | len |= LengthHint::exact(3); |
292 | | assert_eq!(len, LengthHint::between(5, 3)); |
293 | | } |
294 | | } |