/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerovec-0.11.6/src/varzerovec/lengthless.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 super::components::VarZeroVecComponents; |
6 | | use super::*; |
7 | | use crate::ule::*; |
8 | | use core::marker::PhantomData; |
9 | | |
10 | | /// A slice representing the index and data tables of a [`VarZeroVec`], |
11 | | /// *without* any length fields. The length field is expected to be stored elsewhere. |
12 | | /// |
13 | | /// Without knowing the length this is of course unsafe to use directly. |
14 | | #[repr(transparent)] |
15 | | #[derive(PartialEq, Eq)] |
16 | | pub(crate) struct VarZeroLengthlessSlice<T: ?Sized, F> { |
17 | | marker: PhantomData<(F, T)>, |
18 | | /// The original slice this was constructed from |
19 | | // Safety invariant: This field must have successfully passed through |
20 | | // VarZeroVecComponents::parse_bytes_with_length() with the length |
21 | | // associated with this value. |
22 | | entire_slice: [u8], |
23 | | } |
24 | | |
25 | | impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroLengthlessSlice<T, F> { |
26 | | /// Obtain a [`VarZeroVecComponents`] borrowing from the internal buffer |
27 | | /// |
28 | | /// Safety: `len` must be the length associated with this value |
29 | | #[inline] |
30 | 0 | pub(crate) unsafe fn as_components<'a>(&'a self, len: u32) -> VarZeroVecComponents<'a, T, F> { |
31 | | unsafe { |
32 | | // safety: VarZeroSlice is guaranteed to parse here |
33 | 0 | VarZeroVecComponents::from_bytes_unchecked_with_length(len, &self.entire_slice) |
34 | | } |
35 | 0 | } Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<[u8], zerovec::varzerovec::components::Index16>>::as_components Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<_, _>>::as_components |
36 | | |
37 | | /// Parse a [`VarZeroLengthlessSlice`] from a slice of the appropriate format |
38 | | /// |
39 | | /// Slices of the right format can be obtained via [`VarZeroSlice::as_bytes()`] |
40 | 0 | pub fn parse_bytes<'a>(len: u32, slice: &'a [u8]) -> Result<&'a Self, UleError> { |
41 | 0 | let _ = VarZeroVecComponents::<T, F>::parse_bytes_with_length(len, slice) |
42 | 0 | .map_err(|_| UleError::parse::<Self>())?; |
43 | | unsafe { |
44 | | // Safety: We just verified that it is of the correct format. |
45 | 0 | Ok(Self::from_bytes_unchecked(slice)) |
46 | | } |
47 | 0 | } |
48 | | |
49 | | /// Uses a `&[u8]` buffer as a `VarZeroLengthlessSlice<T>` without any verification. |
50 | | /// |
51 | | /// # Safety |
52 | | /// |
53 | | /// `bytes` need to be an output from [`VarZeroLengthlessSlice::as_bytes()`], or alternatively |
54 | | /// successfully pass through `parse_bytes` (with `len`) |
55 | | /// |
56 | | /// The length associated with this value will be the length associated with the original slice. |
57 | 0 | pub(crate) const unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { |
58 | | // self is really just a wrapper around a byte slice |
59 | 0 | &*(bytes as *const [u8] as *const Self) |
60 | 0 | } |
61 | | |
62 | | /// Uses a `&mut [u8]` buffer as a `VarZeroLengthlessSlice<T>` without any verification. |
63 | | /// |
64 | | /// # Safety |
65 | | /// |
66 | | /// `bytes` need to be an output from [`VarZeroLengthlessSlice::as_bytes()`], or alternatively |
67 | | /// be valid to be passed to `from_bytes_unchecked_with_length` |
68 | | /// |
69 | | /// The length associated with this value will be the length associated with the original slice. |
70 | 0 | pub(crate) unsafe fn from_bytes_unchecked_mut(bytes: &mut [u8]) -> &mut Self { |
71 | | // self is really just a wrapper around a byte slice |
72 | 0 | &mut *(bytes as *mut [u8] as *mut VarZeroLengthlessSlice<T, F>) |
73 | 0 | } Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<[u8], zerovec::varzerovec::components::Index16>>::from_bytes_unchecked_mut Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<_, _>>::from_bytes_unchecked_mut |
74 | | |
75 | | /// Get one of this slice's elements |
76 | | /// |
77 | | /// # Safety |
78 | | /// |
79 | | /// `index` must be in range, and `len` must be the length associated with this |
80 | | /// instance of [`VarZeroLengthlessSlice`]. |
81 | 0 | pub(crate) unsafe fn get_unchecked(&self, len: u32, idx: usize) -> &T { |
82 | 0 | self.as_components(len).get_unchecked(idx) |
83 | 0 | } Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<[u8], zerovec::varzerovec::components::Index16>>::get_unchecked Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<_, _>>::get_unchecked |
84 | | |
85 | | /// Get a reference to the entire encoded backing buffer of this slice |
86 | | /// |
87 | | /// The bytes can be passed back to [`Self::parse_bytes()`]. |
88 | | /// |
89 | | /// To take the bytes as a vector, see [`VarZeroVec::into_bytes()`]. |
90 | | #[inline] |
91 | 0 | pub(crate) const fn as_bytes(&self) -> &[u8] { |
92 | 0 | &self.entire_slice |
93 | 0 | } |
94 | | |
95 | | /// Get the bytes behind this as a mutable slice |
96 | | /// |
97 | | /// # Safety |
98 | | /// |
99 | | /// - `len` is the length associated with this [`VarZeroLengthlessSlice`] |
100 | | /// - The resultant slice is only mutated in a way such that it remains a valid `T` |
101 | | /// |
102 | | /// # Panics |
103 | | /// |
104 | | /// Panics when idx is not in bounds for this slice |
105 | 0 | pub(crate) unsafe fn get_bytes_at_mut(&mut self, len: u32, idx: usize) -> &mut [u8] { |
106 | 0 | let components = self.as_components(len); |
107 | 0 | let range = components.get_things_range(idx); |
108 | 0 | let offset = components.get_indices_size(); |
109 | | |
110 | | // get_indices_size() returns the start of the things slice, and get_things_range() |
111 | | // returns a range in-bounds of the things slice |
112 | | #[expect(clippy::indexing_slicing)] |
113 | 0 | &mut self.entire_slice[offset..][range] |
114 | 0 | } Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<[u8], zerovec::varzerovec::components::Index16>>::get_bytes_at_mut Unexecuted instantiation: <zerovec::varzerovec::lengthless::VarZeroLengthlessSlice<_, _>>::get_bytes_at_mut |
115 | | } |