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

zbraniecki / icu4x / 13958601093

19 Mar 2025 04:17PM UTC coverage: 74.164% (-1.5%) from 75.71%
13958601093

push

github

web-flow
Clean up properties docs (#6315)

58056 of 78281 relevant lines covered (74.16%)

819371.32 hits per line

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

96.95
/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
    // random_call exists since usize doesn't have a rand impl. Should always be `random` or empty
10
    ($u:ty, $i:ty, $test:ident $(,$random_call:ident)?) => {
11
        impl $crate::Writeable for $u {
12
            fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
10,397✔
13
                const MAX_LEN: usize = <$u>::MAX.ilog10() as usize + 1;
14
                let mut buf = [b'0'; MAX_LEN];
10,397✔
15
                let mut n = *self;
10,397✔
16
                let mut i = MAX_LEN;
10,397✔
17
                #[allow(clippy::indexing_slicing)] // n < 10^i
18
                while n != 0 {
161,988✔
19
                    i -= 1;
151,591✔
20
                    buf[i] = b'0' + (n % 10) as u8;
151,591✔
21
                    n /= 10;
151,591✔
22
                }
23
                if i == MAX_LEN {
10,476✔
24
                    debug_assert_eq!(*self, 0);
79✔
25
                    i -= 1;
79✔
26
                }
27
                #[allow(clippy::indexing_slicing)] // buf is ASCII
28
                let s = unsafe { core::str::from_utf8_unchecked(&buf[i..]) };
10,397✔
29
                sink.write_str(s)
10,397✔
30
            }
10,397✔
31

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

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

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

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

75
            $(
76

77
                use rand::{rngs::SmallRng, Rng, SeedableRng};
78
                let mut rng = SmallRng::seed_from_u64(4); // chosen by fair dice roll.
5✔
79
                                                          // guaranteed to be random.
80
                for _ in 0..1000 {
5,005✔
81
                    let rand = rng.$random_call::<$u>();
5,000✔
82
                    assert_writeable_eq!(rand, rand.to_string());
83
                }
84
            )?
85
        }
12✔
86
    };
87
}
88

89
impl_write_num!(u8, i8, test_u8, random);
90
impl_write_num!(u16, i16, test_u16, random);
91
impl_write_num!(u32, i32, test_u32, random);
92
impl_write_num!(u64, i64, test_u64, random);
93
impl_write_num!(u128, i128, test_u128, random);
94
impl_write_num!(usize, isize, test_usize);
95

96
impl Writeable for str {
97
    #[inline]
98
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
18,638✔
99
        sink.write_str(self)
18,638✔
100
    }
18,638✔
101

102
    #[inline]
103
    fn writeable_length_hint(&self) -> LengthHint {
152✔
104
        LengthHint::exact(self.len())
152✔
105
    }
152✔
106

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

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

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

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

141
impl Writeable for char {
142
    #[inline]
143
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
50✔
144
        sink.write_char(*self)
50✔
145
    }
50✔
146

147
    #[inline]
148
    fn writeable_length_hint(&self) -> LengthHint {
4✔
149
        LengthHint::exact(self.len_utf8())
4✔
150
    }
4✔
151

152
    #[inline]
153
    fn write_to_string(&self) -> Cow<str> {
4✔
154
        let mut s = String::with_capacity(self.len_utf8());
4✔
155
        s.push(*self);
4✔
156
        Cow::Owned(s)
4✔
157
    }
4✔
158
}
159

160
impl<T: Writeable + ?Sized> Writeable for &T {
161
    #[inline]
162
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
26,844✔
163
        (*self).write_to(sink)
26,844✔
164
    }
26,844✔
165

166
    #[inline]
167
    fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result {
31,943✔
168
        (*self).write_to_parts(sink)
31,943✔
169
    }
31,943✔
170

171
    #[inline]
172
    fn writeable_length_hint(&self) -> LengthHint {
418✔
173
        (*self).writeable_length_hint()
418✔
174
    }
418✔
175

176
    #[inline]
177
    fn write_to_string(&self) -> Cow<str> {
174✔
178
        (*self).write_to_string()
174✔
179
    }
174✔
180
}
181

182
macro_rules! impl_write_smart_pointer {
183
    ($ty:path, T: $extra_bound:path) => {
184
        impl<'a, T: ?Sized + Writeable + $extra_bound> Writeable for $ty {
185
            #[inline]
186
            fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
17✔
187
                core::borrow::Borrow::<T>::borrow(self).write_to(sink)
17✔
188
            }
17✔
189
            #[inline]
190
            fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result {
2,618✔
191
                core::borrow::Borrow::<T>::borrow(self).write_to_parts(sink)
2,618✔
192
            }
2,618✔
193
            #[inline]
194
            fn writeable_length_hint(&self) -> LengthHint {
13✔
195
                core::borrow::Borrow::<T>::borrow(self).writeable_length_hint()
13✔
196
            }
13✔
197
            #[inline]
198
            fn write_to_string(&self) -> Cow<str> {
16✔
199
                core::borrow::Borrow::<T>::borrow(self).write_to_string()
16✔
200
            }
16✔
201
        }
202
    };
203
    ($ty:path) => {
204
        // Add a harmless duplicate Writeable bound
205
        impl_write_smart_pointer!($ty, T: Writeable);
206
    };
207
}
208

209
impl_write_smart_pointer!(Cow<'a, T>, T: alloc::borrow::ToOwned);
210
impl_write_smart_pointer!(alloc::boxed::Box<T>);
211
impl_write_smart_pointer!(alloc::rc::Rc<T>);
212
impl_write_smart_pointer!(alloc::sync::Arc<T>);
213

214
#[test]
215
fn test_string_impls() {
10✔
216
    fn check_writeable_slice<W: Writeable + core::fmt::Display>(writeables: &[W]) {
7✔
217
        assert_writeable_eq!(&writeables[0], "");
7✔
218
        assert_writeable_eq!(&writeables[1], "abc");
7✔
219
        assert!(matches!(writeables[0].write_to_string(), Cow::Borrowed(_)));
7✔
220
        assert!(matches!(writeables[1].write_to_string(), Cow::Borrowed(_)));
7✔
221
    }
7✔
222

223
    // test str impl
224
    let arr: &[&str] = &["", "abc"];
9✔
225
    check_writeable_slice(arr);
9✔
226

227
    // test String impl
228
    let arr: &[String] = &[String::new(), "abc".to_owned()];
9✔
229
    check_writeable_slice(arr);
9✔
230

231
    // test char impl
232
    let chars = ['a', 'β', '你', '😀'];
1✔
233
    for i in 0..chars.len() {
1✔
234
        let s = String::from(chars[i]);
4✔
235
        assert_writeable_eq!(&chars[i], s);
4✔
236
        for j in 0..chars.len() {
20✔
237
            assert_eq!(
16✔
238
                crate::cmp_str(&chars[j], &s),
16✔
239
                chars[j].cmp(&chars[i]),
16✔
240
                "{:?} vs {:?}",
241
                chars[j],
242
                chars[i]
243
            );
244
        }
245
    }
4✔
246

247
    // test Cow impl
248
    let arr: &[Cow<str>] = &[Cow::Borrowed(""), Cow::Owned("abc".to_string())];
1✔
249
    check_writeable_slice(arr);
1✔
250

251
    // test Box impl
252
    let arr: &[Box<str>] = &["".into(), "abc".into()];
1✔
253
    check_writeable_slice(arr);
1✔
254

255
    // test Rc impl
256
    let arr: &[alloc::rc::Rc<str>] = &["".into(), "abc".into()];
1✔
257
    check_writeable_slice(arr);
1✔
258

259
    // test Arc impl
260
    let arr: &[alloc::sync::Arc<str>] = &["".into(), "abc".into()];
1✔
261
    check_writeable_slice(arr);
1✔
262

263
    // test &T impl
264
    let arr: &[&String] = &[&String::new(), &"abc".to_owned()];
1✔
265
    check_writeable_slice(arr);
1✔
266
}
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