icu_provider/baked/
zerotrie.rs
1pub const ID_SEPARATOR: u8 = 0x1E;
11
12pub use crate::DynamicDataMarker;
13use crate::{
14 prelude::{zerofrom::ZeroFrom, *},
15 ule::MaybeAsVarULE,
16};
17pub use zerotrie::ZeroTrieSimpleAscii;
18use zerovec::VarZeroSlice;
19
20fn get_index(
21 trie: ZeroTrieSimpleAscii<&'static [u8]>,
22 id: DataIdentifierBorrowed,
23 attributes_prefix_match: bool,
24) -> Option<usize> {
25 use writeable::Writeable;
26 let mut cursor = trie.cursor();
27 let _is_ascii = id.locale.write_to(&mut cursor);
28 if !id.marker_attributes.is_empty() {
29 cursor.step(ID_SEPARATOR);
30 id.marker_attributes.write_to(&mut cursor).ok()?;
31 loop {
32 if let Some(v) = cursor.take_value() {
33 break Some(v);
34 }
35 if !attributes_prefix_match || cursor.probe(0).is_none() {
36 break None;
37 }
38 }
39 } else {
40 cursor.take_value()
41 }
42}
43
44#[cfg(feature = "alloc")]
45#[allow(clippy::type_complexity)]
46fn iter(
47 trie: &'static ZeroTrieSimpleAscii<&'static [u8]>,
48) -> core::iter::FilterMap<
49 zerotrie::ZeroTrieStringIterator<'static>,
50 fn((alloc::string::String, usize)) -> Option<DataIdentifierCow<'static>>,
51> {
52 use alloc::borrow::ToOwned;
53 trie.iter().filter_map(move |(s, _)| {
54 if let Some((locale, attrs)) = s.split_once(ID_SEPARATOR as char) {
55 Some(DataIdentifierCow::from_owned(
56 DataMarkerAttributes::try_from_str(attrs).ok()?.to_owned(),
57 locale.parse().ok()?,
58 ))
59 } else {
60 s.parse().ok().map(DataIdentifierCow::from_locale)
61 }
62 })
63}
64
65#[derive(Debug)]
67pub struct Data<M: DataMarker> {
68 trie: ZeroTrieSimpleAscii<&'static [u8]>,
70 values: &'static [M::DataStruct],
71}
72
73impl<M: DataMarker> Data<M> {
74 pub const unsafe fn from_trie_and_values_unchecked(
79 trie: ZeroTrieSimpleAscii<&'static [u8]>,
80 values: &'static [M::DataStruct],
81 ) -> Self {
82 Self { trie, values }
83 }
84}
85
86impl<M: DataMarker> super::private::Sealed for Data<M> {}
87impl<M: DataMarker> super::DataStore<M> for Data<M> {
88 fn get(
89 &self,
90 id: DataIdentifierBorrowed,
91 attributes_prefix_match: bool,
92 ) -> Option<DataPayload<M>> {
93 get_index(self.trie, id, attributes_prefix_match)
94 .map(|i| unsafe { self.values.get_unchecked(i) })
96 .map(DataPayload::from_static_ref)
97 }
98
99 #[cfg(feature = "alloc")]
100 type IterReturn = core::iter::FilterMap<
101 zerotrie::ZeroTrieStringIterator<'static>,
102 fn((alloc::string::String, usize)) -> Option<DataIdentifierCow<'static>>,
103 >;
104 #[cfg(feature = "alloc")]
105 fn iter(&'static self) -> Self::IterReturn {
106 iter(&self.trie)
107 }
108}
109
110#[allow(missing_debug_implementations)] pub struct DataForVarULEs<M: DataMarker>
113where
114 M::DataStruct: MaybeAsVarULE,
115 M::DataStruct: ZeroFrom<'static, <M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
116{
117 trie: ZeroTrieSimpleAscii<&'static [u8]>,
119 values: &'static VarZeroSlice<<M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
120}
121
122impl<M: DataMarker> super::private::Sealed for DataForVarULEs<M>
123where
124 M::DataStruct: MaybeAsVarULE,
125 M::DataStruct: ZeroFrom<'static, <M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
126{
127}
128
129impl<M: DataMarker> DataForVarULEs<M>
130where
131 M::DataStruct: MaybeAsVarULE,
132 M::DataStruct: ZeroFrom<'static, <M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
133{
134 pub const unsafe fn from_trie_and_values_unchecked(
139 trie: ZeroTrieSimpleAscii<&'static [u8]>,
140 values: &'static VarZeroSlice<<M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
141 ) -> Self {
142 Self { trie, values }
143 }
144}
145
146impl<M: DataMarker> super::DataStore<M> for DataForVarULEs<M>
147where
148 M::DataStruct: MaybeAsVarULE,
149 M::DataStruct: ZeroFrom<'static, <M::DataStruct as MaybeAsVarULE>::EncodedStruct>,
150{
151 fn get(
152 &self,
153 id: DataIdentifierBorrowed,
154 attributes_prefix_match: bool,
155 ) -> Option<DataPayload<M>> {
156 get_index(self.trie, id, attributes_prefix_match)
157 .map(|i| unsafe { self.values.get_unchecked(i) })
159 .map(M::DataStruct::zero_from)
160 .map(DataPayload::from_owned)
161 }
162
163 #[cfg(feature = "alloc")]
164 type IterReturn = core::iter::FilterMap<
165 zerotrie::ZeroTrieStringIterator<'static>,
166 fn((alloc::string::String, usize)) -> Option<DataIdentifierCow<'static>>,
167 >;
168 #[cfg(feature = "alloc")]
169 fn iter(&'static self) -> Self::IterReturn {
170 iter(&self.trie)
171 }
172}