Coverage Report

Created: 2025-08-29 06:18

/rust/registry/src/index.crates.io-6f17d22bba15001f/tinystr-0.7.6/src/ule.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 crate::{TinyAsciiStr, UnvalidatedTinyAsciiStr};
6
use zerovec::maps::ZeroMapKV;
7
use zerovec::ule::*;
8
use zerovec::{ZeroSlice, ZeroVec};
9
10
// Safety (based on the safety checklist on the ULE trait):
11
//  1. TinyAsciiStr does not include any uninitialized or padding bytes.
12
//     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
13
//  2. TinyAsciiStr is aligned to 1 byte.
14
//     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
15
//  3. The impl of validate_byte_slice() returns an error if any byte is not valid.
16
//  4. The impl of validate_byte_slice() returns an error if there are extra bytes.
17
//  5. The other ULE methods use the default impl.
18
//  6. TinyAsciiStr byte equality is semantic equality
19
unsafe impl<const N: usize> ULE for TinyAsciiStr<N> {
20
    #[inline]
21
0
    fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> {
22
0
        if bytes.len() % N != 0 {
23
0
            return Err(ZeroVecError::length::<Self>(bytes.len()));
24
0
        }
25
        // Validate the bytes
26
0
        for chunk in bytes.chunks_exact(N) {
27
0
            let _ = TinyAsciiStr::<N>::from_bytes_inner(chunk, 0, N, true)
28
0
                .map_err(|_| ZeroVecError::parse::<Self>())?;
29
        }
30
0
        Ok(())
31
0
    }
32
}
33
34
impl<const N: usize> AsULE for TinyAsciiStr<N> {
35
    type ULE = Self;
36
37
    #[inline]
38
0
    fn to_unaligned(self) -> Self::ULE {
39
0
        self
40
0
    }
41
42
    #[inline]
43
0
    fn from_unaligned(unaligned: Self::ULE) -> Self {
44
0
        unaligned
45
0
    }
Unexecuted instantiation: <tinystr::ascii::TinyAsciiStr<16> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::ascii::TinyAsciiStr<_> as zerovec::ule::AsULE>::from_unaligned
46
}
47
48
impl<'a, const N: usize> ZeroMapKV<'a> for TinyAsciiStr<N> {
49
    type Container = ZeroVec<'a, TinyAsciiStr<N>>;
50
    type Slice = ZeroSlice<TinyAsciiStr<N>>;
51
    type GetType = TinyAsciiStr<N>;
52
    type OwnedType = TinyAsciiStr<N>;
53
}
54
55
// Safety (based on the safety checklist on the ULE trait):
56
//  1. UnvalidatedTinyAsciiStr does not include any uninitialized or padding bytes.
57
//     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
58
//  2. UnvalidatedTinyAsciiStr is aligned to 1 byte.
59
//     (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
60
//  3. The impl of validate_byte_slice() returns an error if any byte is not valid.
61
//  4. The impl of validate_byte_slice() returns an error if there are extra bytes.
62
//  5. The other ULE methods use the default impl.
63
//  6. UnvalidatedTinyAsciiStr byte equality is semantic equality
64
unsafe impl<const N: usize> ULE for UnvalidatedTinyAsciiStr<N> {
65
    #[inline]
66
0
    fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> {
67
0
        if bytes.len() % N != 0 {
68
0
            return Err(ZeroVecError::length::<Self>(bytes.len()));
69
0
        }
70
0
        Ok(())
71
0
    }
72
}
73
74
impl<const N: usize> AsULE for UnvalidatedTinyAsciiStr<N> {
75
    type ULE = Self;
76
77
    #[inline]
78
0
    fn to_unaligned(self) -> Self::ULE {
79
0
        self
80
0
    }
81
82
    #[inline]
83
0
    fn from_unaligned(unaligned: Self::ULE) -> Self {
84
0
        unaligned
85
0
    }
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<2> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<3> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<4> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<7> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<8> as zerovec::ule::AsULE>::from_unaligned
Unexecuted instantiation: <tinystr::unvalidated::UnvalidatedTinyAsciiStr<_> as zerovec::ule::AsULE>::from_unaligned
86
}
87
88
impl<'a, const N: usize> ZeroMapKV<'a> for UnvalidatedTinyAsciiStr<N> {
89
    type Container = ZeroVec<'a, UnvalidatedTinyAsciiStr<N>>;
90
    type Slice = ZeroSlice<UnvalidatedTinyAsciiStr<N>>;
91
    type GetType = UnvalidatedTinyAsciiStr<N>;
92
    type OwnedType = UnvalidatedTinyAsciiStr<N>;
93
}
94
95
#[cfg(test)]
96
mod test {
97
    use crate::*;
98
    use zerovec::*;
99
100
    #[test]
101
    fn test_zerovec() {
102
        let mut vec = ZeroVec::<TinyAsciiStr<7>>::new();
103
104
        vec.with_mut(|v| v.push("foobar".parse().unwrap()));
105
        vec.with_mut(|v| v.push("baz".parse().unwrap()));
106
        vec.with_mut(|v| v.push("quux".parse().unwrap()));
107
108
        let bytes = vec.as_bytes();
109
110
        let vec: ZeroVec<TinyAsciiStr<7>> = ZeroVec::parse_byte_slice(bytes).unwrap();
111
112
        assert_eq!(&*vec.get(0).unwrap(), "foobar");
113
        assert_eq!(&*vec.get(1).unwrap(), "baz");
114
        assert_eq!(&*vec.get(2).unwrap(), "quux");
115
    }
116
}