Coverage Report

Created: 2026-02-14 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/src/builder/bytestr.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 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
        // 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
        // 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
        // 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
    #[allow(clippy::indexing_slicing)] // "panic" is in method name
77
0
    pub(crate) const fn byte_at_or_panic(&self, index: usize) -> u8 {
78
0
        self.0[index]
79
0
    }
80
81
    /// Const function to evaluate `self < other`.
82
    #[allow(clippy::indexing_slicing)] // in-range loop conditions
83
0
    pub(crate) const fn is_less_then(&self, other: &Self) -> bool {
84
0
        let mut i = 0;
85
0
        while i < self.len() && i < other.len() {
86
0
            if self.0[i] < other.0[i] {
87
0
                return true;
88
0
            }
89
0
            if self.0[i] > other.0[i] {
90
0
                return false;
91
0
            }
92
0
            i += 1;
93
        }
94
0
        self.len() < other.len()
95
0
    }
96
97
    /// Const function to evaluate `self[..prefix_len] == other[..prefix_len]`
98
    ///
99
    /// # Panics
100
    ///
101
    /// Panics if `prefix_len` is longer than either this string or the other string
102
    #[allow(clippy::indexing_slicing)] // in-range loop conditions
103
0
    pub(crate) const fn prefix_eq(&self, other: &ByteStr, prefix_len: usize) -> bool {
104
0
        assert!(prefix_len <= self.len());
105
0
        assert!(prefix_len <= other.len());
106
0
        let mut i = 0;
107
0
        while i < prefix_len {
108
0
            if self.0[i] != other.0[i] {
109
0
                return false;
110
0
            }
111
0
            i += 1;
112
        }
113
0
        true
114
0
    }
115
}
116
117
impl Borrow<[u8]> for ByteStr {
118
0
    fn borrow(&self) -> &[u8] {
119
0
        self.as_bytes()
120
0
    }
121
}
122
123
#[cfg(feature = "alloc")]
124
impl Borrow<[u8]> for alloc::boxed::Box<ByteStr> {
125
    fn borrow(&self) -> &[u8] {
126
        self.as_bytes()
127
    }
128
}