/rust/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.1/src/cmp.rs
Line | Count | Source |
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::Writeable; |
6 | | use core::cmp::Ordering; |
7 | | use core::fmt; |
8 | | |
9 | | struct WriteComparator<'a> { |
10 | | code_units: &'a [u8], |
11 | | result: Ordering, |
12 | | } |
13 | | |
14 | | /// This is an infallible impl. Functions always return Ok, not Err. |
15 | | impl fmt::Write for WriteComparator<'_> { |
16 | | #[inline] |
17 | 0 | fn write_str(&mut self, other: &str) -> fmt::Result { |
18 | 0 | if self.result != Ordering::Equal { |
19 | 0 | return Ok(()); |
20 | 0 | } |
21 | 0 | let (this, remainder) = self |
22 | 0 | .code_units |
23 | 0 | .split_at_checked(other.len()) |
24 | 0 | .unwrap_or((self.code_units, &[])); |
25 | 0 | self.code_units = remainder; |
26 | 0 | self.result = this.cmp(other.as_bytes()); |
27 | 0 | Ok(()) |
28 | 0 | } Unexecuted instantiation: <writeable::cmp::WriteComparator as core::fmt::Write>::write_str Unexecuted instantiation: <writeable::cmp::WriteComparator as core::fmt::Write>::write_str |
29 | | } |
30 | | |
31 | | impl<'a> WriteComparator<'a> { |
32 | | #[inline] |
33 | 0 | fn new(code_units: &'a [u8]) -> Self { |
34 | 0 | Self { |
35 | 0 | code_units, |
36 | 0 | result: Ordering::Equal, |
37 | 0 | } |
38 | 0 | } Unexecuted instantiation: <writeable::cmp::WriteComparator>::new Unexecuted instantiation: <writeable::cmp::WriteComparator>::new |
39 | | |
40 | | #[inline] |
41 | 0 | fn finish(self) -> Ordering { |
42 | 0 | if matches!(self.result, Ordering::Equal) && !self.code_units.is_empty() { |
43 | | // Self is longer than Other |
44 | 0 | Ordering::Greater |
45 | | } else { |
46 | 0 | self.result |
47 | | } |
48 | 0 | } Unexecuted instantiation: <writeable::cmp::WriteComparator>::finish Unexecuted instantiation: <writeable::cmp::WriteComparator>::finish |
49 | | } |
50 | | |
51 | | /// Compares the contents of a [`Writeable`] to the given UTF-8 bytes without allocating memory. |
52 | | /// |
53 | | /// For more details, see: [`cmp_str`] |
54 | 0 | pub fn cmp_utf8(writeable: &impl Writeable, other: &[u8]) -> Ordering { |
55 | 0 | let mut wc = WriteComparator::new(other); |
56 | 0 | let _ = writeable.write_to(&mut wc); |
57 | 0 | wc.finish().reverse() |
58 | 0 | } Unexecuted instantiation: writeable::cmp::cmp_utf8::<icu_locale_core::data::DataLocale> Unexecuted instantiation: writeable::cmp::cmp_utf8::<icu_locale_core::langid::LanguageIdentifier> Unexecuted instantiation: writeable::cmp::cmp_utf8::<icu_locale_core::locale::Locale> Unexecuted instantiation: writeable::cmp::cmp_utf8::<icu_locale_core::extensions::unicode::value::Value> Unexecuted instantiation: writeable::cmp::cmp_utf8::<icu_locale_core::extensions::unicode::keywords::Keywords> Unexecuted instantiation: writeable::cmp::cmp_utf8::<_> |
59 | | |
60 | | /// Compares the contents of a `Writeable` to the given bytes |
61 | | /// without allocating a String to hold the `Writeable` contents. |
62 | | /// |
63 | | /// This returns a lexicographical comparison, the same as if the Writeable |
64 | | /// were first converted to a String and then compared with `Ord`. For a |
65 | | /// string ordering suitable for display to end users, use a localized |
66 | | /// collation crate, such as `icu_collator`. |
67 | | /// |
68 | | /// # Examples |
69 | | /// |
70 | | /// ``` |
71 | | /// use core::cmp::Ordering; |
72 | | /// use core::fmt; |
73 | | /// use writeable::Writeable; |
74 | | /// |
75 | | /// struct WelcomeMessage<'s> { |
76 | | /// pub name: &'s str, |
77 | | /// } |
78 | | /// |
79 | | /// impl<'s> Writeable for WelcomeMessage<'s> { |
80 | | /// // see impl in Writeable docs |
81 | | /// # fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { |
82 | | /// # sink.write_str("Hello, ")?; |
83 | | /// # sink.write_str(self.name)?; |
84 | | /// # sink.write_char('!')?; |
85 | | /// # Ok(()) |
86 | | /// # } |
87 | | /// } |
88 | | /// |
89 | | /// let message = WelcomeMessage { name: "Alice" }; |
90 | | /// let message_str = message.write_to_string(); |
91 | | /// |
92 | | /// assert_eq!(Ordering::Equal, writeable::cmp_str(&message, "Hello, Alice!")); |
93 | | /// |
94 | | /// assert_eq!(Ordering::Greater, writeable::cmp_str(&message, "Alice!")); |
95 | | /// assert_eq!(Ordering::Greater, (*message_str).cmp("Alice!")); |
96 | | /// |
97 | | /// assert_eq!(Ordering::Less, writeable::cmp_str(&message, "Hello, Bob!")); |
98 | | /// assert_eq!(Ordering::Less, (*message_str).cmp("Hello, Bob!")); |
99 | | /// ``` |
100 | | #[inline] |
101 | 0 | pub fn cmp_str(writeable: &impl Writeable, other: &str) -> Ordering { |
102 | 0 | cmp_utf8(writeable, other.as_bytes()) |
103 | 0 | } |
104 | | |
105 | | #[cfg(test)] |
106 | | mod tests { |
107 | | use super::*; |
108 | | use core::fmt::Write; |
109 | | |
110 | | mod data { |
111 | | include!("../tests/data/data.rs"); |
112 | | } |
113 | | |
114 | | #[test] |
115 | | fn test_write_char() { |
116 | | for a in data::KEBAB_CASE_STRINGS { |
117 | | for b in data::KEBAB_CASE_STRINGS { |
118 | | let mut wc = WriteComparator::new(a.as_bytes()); |
119 | | for ch in b.chars() { |
120 | | wc.write_char(ch).unwrap(); |
121 | | } |
122 | | assert_eq!(a.cmp(b), wc.finish(), "{a} <=> {b}"); |
123 | | } |
124 | | } |
125 | | } |
126 | | |
127 | | #[test] |
128 | | fn test_write_str() { |
129 | | for a in data::KEBAB_CASE_STRINGS { |
130 | | for b in data::KEBAB_CASE_STRINGS { |
131 | | let mut wc = WriteComparator::new(a.as_bytes()); |
132 | | wc.write_str(b).unwrap(); |
133 | | assert_eq!(a.cmp(b), wc.finish(), "{a} <=> {b}"); |
134 | | } |
135 | | } |
136 | | } |
137 | | |
138 | | #[test] |
139 | | fn test_mixed() { |
140 | | for a in data::KEBAB_CASE_STRINGS { |
141 | | for b in data::KEBAB_CASE_STRINGS { |
142 | | let mut wc = WriteComparator::new(a.as_bytes()); |
143 | | let mut first = true; |
144 | | for substr in b.split('-') { |
145 | | if first { |
146 | | first = false; |
147 | | } else { |
148 | | wc.write_char('-').unwrap(); |
149 | | } |
150 | | wc.write_str(substr).unwrap(); |
151 | | } |
152 | | assert_eq!(a.cmp(b), wc.finish(), "{a} <=> {b}"); |
153 | | } |
154 | | } |
155 | | } |
156 | | } |