/rust/registry/src/index.crates.io-6f17d22bba15001f/zerotrie-0.1.3/src/builder/bytestr.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 core::borrow::Borrow; |
6 | | |
7 | | #[cfg(feature = "serde")] |
8 | | use alloc::boxed::Box; |
9 | | |
10 | | /// A struct transparent over `[u8]` with convenient helper functions. |
11 | | #[repr(transparent)] |
12 | | #[derive(PartialEq, Eq, PartialOrd, Ord)] |
13 | | pub(crate) struct ByteStr([u8]); |
14 | | |
15 | | impl ByteStr { |
16 | 0 | pub const fn from_byte_slice_with_value<'a, 'l>( |
17 | 0 | input: &'l [(&'a [u8], usize)], |
18 | 0 | ) -> &'l [(&'a ByteStr, usize)] { |
19 | 0 | // Safety: [u8] and ByteStr have the same layout and invariants |
20 | 0 | unsafe { core::mem::transmute(input) } |
21 | 0 | } |
22 | | |
23 | 0 | pub const fn from_str_slice_with_value<'a, 'l>( |
24 | 0 | input: &'l [(&'a str, usize)], |
25 | 0 | ) -> &'l [(&'a ByteStr, usize)] { |
26 | 0 | // Safety: str and ByteStr have the same layout, and ByteStr is less restrictive |
27 | 0 | unsafe { core::mem::transmute(input) } |
28 | 0 | } |
29 | | |
30 | 0 | pub fn from_bytes(input: &[u8]) -> &Self { |
31 | 0 | // Safety: [u8] and ByteStr have the same layout and invariants |
32 | 0 | unsafe { core::mem::transmute(input) } |
33 | 0 | } |
34 | | |
35 | | #[cfg(feature = "serde")] |
36 | | pub fn from_boxed_bytes(input: Box<[u8]>) -> Box<Self> { |
37 | | // Safety: [u8] and ByteStr have the same layout and invariants |
38 | | unsafe { core::mem::transmute(input) } |
39 | | } |
40 | | |
41 | | #[allow(dead_code)] // may want this in the future |
42 | 0 | pub fn from_str(input: &str) -> &Self { |
43 | 0 | Self::from_bytes(input.as_bytes()) |
44 | 0 | } |
45 | | |
46 | | #[allow(dead_code)] // may want this in the future |
47 | 0 | pub fn empty() -> &'static Self { |
48 | 0 | Self::from_bytes(&[]) |
49 | 0 | } |
50 | | |
51 | | #[allow(dead_code)] // not used in all features |
52 | 0 | pub const fn as_bytes(&self) -> &[u8] { |
53 | 0 | &self.0 |
54 | 0 | } |
55 | | |
56 | 0 | pub const fn len(&self) -> usize { |
57 | 0 | self.0.len() |
58 | 0 | } |
59 | | |
60 | | #[allow(dead_code)] // not used in all features |
61 | 0 | pub fn is_all_ascii(&self) -> bool { |
62 | 0 | for byte in self.0.iter() { |
63 | 0 | if !byte.is_ascii() { |
64 | 0 | return false; |
65 | 0 | } |
66 | | } |
67 | 0 | true |
68 | 0 | } |
69 | | |
70 | | #[allow(dead_code)] // may want this in the future |
71 | 0 | pub(crate) fn byte_at(&self, index: usize) -> Option<u8> { |
72 | 0 | self.0.get(index).copied() |
73 | 0 | } |
74 | | |
75 | | /// Returns the byte at the given index, panicking if out of bounds. |
76 | 0 | pub(crate) const fn byte_at_or_panic(&self, index: usize) -> u8 { |
77 | 0 | self.0[index] |
78 | 0 | } |
79 | | |
80 | | /// Const function to evaluate `self < other`. |
81 | 0 | pub(crate) const fn is_less_then(&self, other: &Self) -> bool { |
82 | 0 | let mut i = 0; |
83 | 0 | while i < self.len() && i < other.len() { |
84 | 0 | if self.0[i] < other.0[i] { |
85 | 0 | return true; |
86 | 0 | } |
87 | 0 | if self.0[i] > other.0[i] { |
88 | 0 | return false; |
89 | 0 | } |
90 | 0 | i += 1; |
91 | | } |
92 | 0 | self.len() < other.len() |
93 | 0 | } |
94 | | |
95 | | /// Const function to evaluate `self[..prefix_len] == other[..prefix_len]` |
96 | 0 | pub(crate) const fn prefix_eq(&self, other: &ByteStr, prefix_len: usize) -> bool { |
97 | 0 | assert!(prefix_len <= self.len()); |
98 | 0 | assert!(prefix_len <= other.len()); |
99 | 0 | let mut i = 0; |
100 | 0 | while i < prefix_len { |
101 | 0 | if self.0[i] != other.0[i] { |
102 | 0 | return false; |
103 | 0 | } |
104 | 0 | i += 1; |
105 | | } |
106 | 0 | true |
107 | 0 | } |
108 | | } |
109 | | |
110 | | impl Borrow<[u8]> for ByteStr { |
111 | 0 | fn borrow(&self) -> &[u8] { |
112 | 0 | self.as_bytes() |
113 | 0 | } |
114 | | } |
115 | | |
116 | | #[cfg(feature = "alloc")] |
117 | | impl Borrow<[u8]> for alloc::boxed::Box<ByteStr> { |
118 | 0 | fn borrow(&self) -> &[u8] { |
119 | 0 | self.as_bytes() |
120 | 0 | } |
121 | | } |