• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zbraniecki / icu4x / 8611306223

09 Apr 2024 06:09AM UTC coverage: 76.234% (+0.2%) from 75.985%
8611306223

push

github

web-flow
Updating tutorial lock files (#4784)

Needed for https://github.com/unicode-org/icu4x/pull/4776

51696 of 67812 relevant lines covered (76.23%)

512021.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.56
/utils/writeable/src/impls.rs
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::*;
6
use core::fmt;
7

8
macro_rules! impl_write_num {
9
    ($u:ty, $i:ty, $test:ident) => {
10
        impl $crate::Writeable for $u {
11
            fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
12,316✔
12
                const MAX_LEN: usize = <$u>::MAX.ilog10() as usize + 1;
13
                let mut buf = [b'0'; MAX_LEN];
12,316✔
14
                let mut n = *self;
12,316✔
15
                let mut i = MAX_LEN;
12,316✔
16
                #[allow(clippy::indexing_slicing)] // n < 10^i
17
                while n != 0 {
202,353✔
18
                    i -= 1;
190,037✔
19
                    buf[i] = b'0' + (n % 10) as u8;
190,037✔
20
                    n /= 10;
190,037✔
21
                }
22
                if i == MAX_LEN {
12,382✔
23
                    debug_assert_eq!(*self, 0);
66✔
24
                    i -= 1;
66✔
25
                }
26
                #[allow(clippy::indexing_slicing)] // buf is ASCII
27
                let s = unsafe { core::str::from_utf8_unchecked(&buf[i..]) };
12,316✔
28
                sink.write_str(s)
12,316✔
29
            }
12,316✔
30

31
            fn writeable_length_hint(&self) -> $crate::LengthHint {
12,306✔
32
                LengthHint::exact(self.checked_ilog10().unwrap_or(0) as usize + 1)
12,306✔
33
            }
12,306✔
34
        }
35

36
        impl $crate::Writeable for $i {
37
            fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
226✔
38
                if self.is_negative() {
226✔
39
                    sink.write_str("-")?;
81✔
40
                }
41
                self.unsigned_abs().write_to(sink)
226✔
42
            }
226✔
43

44
            fn writeable_length_hint(&self) -> $crate::LengthHint {
218✔
45
                $crate::LengthHint::exact(if self.is_negative() { 1 } else { 0 })
218✔
46
                    + self.unsigned_abs().writeable_length_hint()
218✔
47
            }
218✔
48
        }
49

50
        #[test]
51
        fn $test() {
12✔
52
            use $crate::assert_writeable_eq;
53
            assert_writeable_eq!(&(0 as $u), "0");
6✔
54
            assert_writeable_eq!(&(0 as $i), "0");
6✔
55
            assert_writeable_eq!(&(-0 as $i), "0");
6✔
56
            assert_writeable_eq!(&(1 as $u), "1");
6✔
57
            assert_writeable_eq!(&(1 as $i), "1");
6✔
58
            assert_writeable_eq!(&(-1 as $i), "-1");
6✔
59
            assert_writeable_eq!(&(9 as $u), "9");
6✔
60
            assert_writeable_eq!(&(9 as $i), "9");
6✔
61
            assert_writeable_eq!(&(-9 as $i), "-9");
6✔
62
            assert_writeable_eq!(&(10 as $u), "10");
6✔
63
            assert_writeable_eq!(&(10 as $i), "10");
6✔
64
            assert_writeable_eq!(&(-10 as $i), "-10");
6✔
65
            assert_writeable_eq!(&(99 as $u), "99");
6✔
66
            assert_writeable_eq!(&(99 as $i), "99");
6✔
67
            assert_writeable_eq!(&(-99 as $i), "-99");
6✔
68
            assert_writeable_eq!(&(100 as $u), "100");
6✔
69
            assert_writeable_eq!(&(-100 as $i), "-100");
6✔
70
            assert_writeable_eq!(&<$u>::MAX, <$u>::MAX.to_string());
6✔
71
            assert_writeable_eq!(&<$i>::MAX, <$i>::MAX.to_string());
6✔
72
            assert_writeable_eq!(&<$i>::MIN, <$i>::MIN.to_string());
6✔
73

74
            use rand::{rngs::SmallRng, Rng, SeedableRng};
75
            let mut rng = SmallRng::seed_from_u64(4); // chosen by fair dice roll.
6✔
76
                                                      // guaranteed to be random.
77
            for _ in 0..1000 {
6,006✔
78
                let rand = rng.gen::<$u>();
6,000✔
79
                assert_writeable_eq!(rand, rand.to_string());
6,000✔
80
            }
81
        }
12✔
82
    };
83
}
84

85
impl_write_num!(u8, i8, test_u8);
86
impl_write_num!(u16, i16, test_u16);
87
impl_write_num!(u32, i32, test_u32);
88
impl_write_num!(u64, i64, test_u64);
89
impl_write_num!(u128, i128, test_u128);
90
impl_write_num!(usize, isize, test_usize);
91

92
impl Writeable for str {
93
    #[inline]
94
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
18,386✔
95
        sink.write_str(self)
18,386✔
96
    }
18,386✔
97

98
    #[inline]
99
    fn writeable_length_hint(&self) -> LengthHint {
3,739✔
100
        LengthHint::exact(self.len())
3,739✔
101
    }
3,739✔
102

103
    /// Returns a borrowed `str`.
104
    ///
105
    /// # Examples
106
    ///
107
    /// ```
108
    /// use std::borrow::Cow;
109
    /// use writeable::Writeable;
110
    ///
111
    /// let cow = "foo".write_to_string();
112
    /// assert!(matches!(cow, Cow::Borrowed(_)));
113
    /// ```
114
    #[inline]
115
    fn write_to_string(&self) -> Cow<str> {
21✔
116
        Cow::Borrowed(self)
21✔
117
    }
21✔
118

119
    #[inline]
120
    fn write_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering {
×
121
        self.as_bytes().cmp(other)
×
122
    }
×
123
}
124

125
impl Writeable for String {
126
    #[inline]
127
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
4✔
128
        sink.write_str(self)
4✔
129
    }
4✔
130

131
    #[inline]
132
    fn writeable_length_hint(&self) -> LengthHint {
4✔
133
        LengthHint::exact(self.len())
4✔
134
    }
4✔
135

136
    #[inline]
137
    fn write_to_string(&self) -> Cow<str> {
8✔
138
        Cow::Borrowed(self)
8✔
139
    }
8✔
140

141
    #[inline]
142
    fn write_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering {
×
143
        self.as_bytes().cmp(other)
×
144
    }
×
145
}
146

147
impl Writeable for char {
148
    #[inline]
149
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
4✔
150
        sink.write_char(*self)
4✔
151
    }
4✔
152

153
    #[inline]
154
    fn writeable_length_hint(&self) -> LengthHint {
4✔
155
        LengthHint::exact(self.len_utf8())
4✔
156
    }
4✔
157

158
    #[inline]
159
    fn write_to_string(&self) -> Cow<str> {
4✔
160
        let mut s = String::with_capacity(self.len_utf8());
4✔
161
        s.push(*self);
4✔
162
        Cow::Owned(s)
4✔
163
    }
4✔
164

165
    #[inline]
166
    fn write_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering {
16✔
167
        self.encode_utf8(&mut [0u8; 4]).as_bytes().cmp(other)
16✔
168
    }
16✔
169
}
170

171
impl<T: Writeable + ?Sized> Writeable for &T {
172
    #[inline]
173
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
24,063✔
174
        (*self).write_to(sink)
24,063✔
175
    }
24,063✔
176

177
    #[inline]
178
    fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result {
544✔
179
        (*self).write_to_parts(sink)
544✔
180
    }
544✔
181

182
    #[inline]
183
    fn writeable_length_hint(&self) -> LengthHint {
418✔
184
        (*self).writeable_length_hint()
418✔
185
    }
418✔
186

187
    #[inline]
188
    fn write_to_string(&self) -> Cow<str> {
174✔
189
        (*self).write_to_string()
174✔
190
    }
174✔
191

192
    #[inline]
193
    fn write_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering {
194
        (*self).write_cmp_bytes(other)
195
    }
196
}
197

198
macro_rules! impl_write_smart_pointer {
199
    ($ty:path, T: $extra_bound:path) => {
200
        impl<'a, T: ?Sized + Writeable + $extra_bound> Writeable for $ty {
201
            #[inline]
202
            fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
5✔
203
                core::borrow::Borrow::<T>::borrow(self).write_to(sink)
5✔
204
            }
5✔
205
            #[inline]
206
            fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result {
8✔
207
                core::borrow::Borrow::<T>::borrow(self).write_to_parts(sink)
8✔
208
            }
8✔
209
            #[inline]
210
            fn writeable_length_hint(&self) -> LengthHint {
13✔
211
                core::borrow::Borrow::<T>::borrow(self).writeable_length_hint()
13✔
212
            }
13✔
213
            #[inline]
214
            fn write_to_string(&self) -> Cow<str> {
16✔
215
                core::borrow::Borrow::<T>::borrow(self).write_to_string()
16✔
216
            }
16✔
217
            #[inline]
218
            fn write_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering {
219
                core::borrow::Borrow::<T>::borrow(self).write_cmp_bytes(other)
220
            }
221
        }
222
    };
223
    ($ty:path) => {
224
        // Add a harmless duplicate Writeable bound
225
        impl_write_smart_pointer!($ty, T: Writeable);
226
    };
227
}
228

229
impl_write_smart_pointer!(Cow<'a, T>, T: alloc::borrow::ToOwned);
230
impl_write_smart_pointer!(alloc::boxed::Box<T>);
231
impl_write_smart_pointer!(alloc::rc::Rc<T>);
232
impl_write_smart_pointer!(alloc::sync::Arc<T>);
233

234
#[test]
235
fn test_string_impls() {
10✔
236
    fn check_writeable_slice<W: Writeable + core::fmt::Display>(writeables: &[W]) {
7✔
237
        assert_writeable_eq!(&writeables[0], "");
7✔
238
        assert_writeable_eq!(&writeables[1], "abc");
7✔
239
        assert!(matches!(writeables[0].write_to_string(), Cow::Borrowed(_)));
7✔
240
        assert!(matches!(writeables[1].write_to_string(), Cow::Borrowed(_)));
7✔
241
    }
7✔
242

243
    // test str impl
244
    let arr: &[&str] = &["", "abc"];
9✔
245
    check_writeable_slice(arr);
9✔
246

247
    // test String impl
248
    let arr: &[String] = &[String::new(), "abc".to_owned()];
9✔
249
    check_writeable_slice(arr);
9✔
250

251
    // test char impl
252
    let chars = ['a', 'β', '你', '😀'];
1✔
253
    for i in 0..chars.len() {
1✔
254
        let s = String::from(chars[i]);
4✔
255
        assert_writeable_eq!(&chars[i], s);
4✔
256
        for j in 0..chars.len() {
20✔
257
            assert_eq!(
16✔
258
                chars[j].write_cmp_bytes(s.as_bytes()),
16✔
259
                chars[j].cmp(&chars[i]),
16✔
260
                "{:?} vs {:?}",
261
                chars[j],
×
262
                chars[i]
×
263
            );
264
        }
265
    }
4✔
266

267
    // test Cow impl
268
    let arr: &[Cow<str>] = &[Cow::Borrowed(""), Cow::Owned("abc".to_string())];
1✔
269
    check_writeable_slice(arr);
1✔
270

271
    // test Box impl
272
    let arr: &[Box<str>] = &["".into(), "abc".into()];
1✔
273
    check_writeable_slice(arr);
1✔
274

275
    // test Rc impl
276
    let arr: &[alloc::rc::Rc<str>] = &["".into(), "abc".into()];
1✔
277
    check_writeable_slice(arr);
1✔
278

279
    // test Arc impl
280
    let arr: &[alloc::sync::Arc<str>] = &["".into(), "abc".into()];
1✔
281
    check_writeable_slice(arr);
1✔
282

283
    // test &T impl
284
    let arr: &[&String] = &[&String::new(), &"abc".to_owned()];
1✔
285
    check_writeable_slice(arr);
1✔
286
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc