Coverage Report

Created: 2025-06-16 06:50

/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
}