1use crate::reader;
6
7use core::borrow::Borrow;
8
9#[cfg(feature = "alloc")]
10use crate::{
11 builder::nonconst::ZeroTrieBuilder, builder::slice_indices::ByteSliceWithIndices,
12 error::ZeroTrieBuildError,
13};
14#[cfg(feature = "alloc")]
15use alloc::{boxed::Box, collections::BTreeMap, collections::VecDeque, string::String, vec::Vec};
16#[cfg(feature = "litemap")]
17use litemap::LiteMap;
18
19#[derive(#[automatically_derived]
impl<Store: ::core::fmt::Debug> ::core::fmt::Debug for ZeroTrie<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "ZeroTrie",
&&self.0)
}
}Debug, #[automatically_derived]
impl<Store: ::core::clone::Clone> ::core::clone::Clone for ZeroTrie<Store> {
#[inline]
fn clone(&self) -> ZeroTrie<Store> {
ZeroTrie(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl<Store: ::core::marker::Copy> ::core::marker::Copy for ZeroTrie<Store> { }Copy, #[automatically_derived]
impl<Store: ::core::cmp::PartialEq> ::core::cmp::PartialEq for ZeroTrie<Store>
{
#[inline]
fn eq(&self, other: &ZeroTrie<Store>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<Store: ::core::cmp::Eq> ::core::cmp::Eq for ZeroTrie<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ZeroTrieFlavor<Store>>;
}
}Eq)]
67#[cfg_attr(feature = "yoke", derive(unsafe impl<'yoke, Store> yoke::Yokeable<'yoke> for ZeroTrie<Store> where
Store: 'static, Self: Sized {
type Output = Self;
#[inline]
fn transform(&self) -> &Self::Output { self }
#[inline]
fn transform_owned(self) -> Self::Output { self }
#[inline]
unsafe fn make(this: Self::Output) -> Self { this }
#[inline]
fn transform_mut<F>(&'yoke mut self, f: F) where F: 'static +
for<'_yoke> FnOnce(&'_yoke mut Self::Output) {
f(self)
}
}yoke::Yokeable))]
69pub struct ZeroTrie<Store>(pub(crate) ZeroTrieFlavor<Store>);
70
71#[derive(#[automatically_derived]
impl<Store: ::core::fmt::Debug> ::core::fmt::Debug for ZeroTrieFlavor<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ZeroTrieFlavor::SimpleAscii(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"SimpleAscii", &__self_0),
ZeroTrieFlavor::PerfectHash(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"PerfectHash", &__self_0),
ZeroTrieFlavor::ExtendedCapacity(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ExtendedCapacity", &__self_0),
}
}
}Debug, #[automatically_derived]
impl<Store: ::core::clone::Clone> ::core::clone::Clone for
ZeroTrieFlavor<Store> {
#[inline]
fn clone(&self) -> ZeroTrieFlavor<Store> {
match self {
ZeroTrieFlavor::SimpleAscii(__self_0) =>
ZeroTrieFlavor::SimpleAscii(::core::clone::Clone::clone(__self_0)),
ZeroTrieFlavor::PerfectHash(__self_0) =>
ZeroTrieFlavor::PerfectHash(::core::clone::Clone::clone(__self_0)),
ZeroTrieFlavor::ExtendedCapacity(__self_0) =>
ZeroTrieFlavor::ExtendedCapacity(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl<Store: ::core::marker::Copy> ::core::marker::Copy for
ZeroTrieFlavor<Store> {
}Copy, #[automatically_derived]
impl<Store: ::core::cmp::PartialEq> ::core::cmp::PartialEq for
ZeroTrieFlavor<Store> {
#[inline]
fn eq(&self, other: &ZeroTrieFlavor<Store>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ZeroTrieFlavor::SimpleAscii(__self_0),
ZeroTrieFlavor::SimpleAscii(__arg1_0)) =>
__self_0 == __arg1_0,
(ZeroTrieFlavor::PerfectHash(__self_0),
ZeroTrieFlavor::PerfectHash(__arg1_0)) =>
__self_0 == __arg1_0,
(ZeroTrieFlavor::ExtendedCapacity(__self_0),
ZeroTrieFlavor::ExtendedCapacity(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl<Store: ::core::cmp::Eq> ::core::cmp::Eq for ZeroTrieFlavor<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ZeroTrieSimpleAscii<Store>>;
let _: ::core::cmp::AssertParamIsEq<ZeroTriePerfectHash<Store>>;
let _: ::core::cmp::AssertParamIsEq<ZeroTrieExtendedCapacity<Store>>;
}
}Eq)]
72pub(crate) enum ZeroTrieFlavor<Store> {
73 SimpleAscii(ZeroTrieSimpleAscii<Store>),
74 PerfectHash(ZeroTriePerfectHash<Store>),
75 ExtendedCapacity(ZeroTrieExtendedCapacity<Store>),
76}
77
78#[repr(transparent)]
114#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::fmt::Debug + ?Sized> ::core::fmt::Debug for
ZeroTrieSimpleAscii<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ZeroTrieSimpleAscii", "store", &&self.store)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::default::Default + ?Sized> ::core::default::Default for
ZeroTrieSimpleAscii<Store> {
#[inline]
fn default() -> ZeroTrieSimpleAscii<Store> {
ZeroTrieSimpleAscii { store: ::core::default::Default::default() }
}
}Default, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::clone::Clone + ?Sized> ::core::clone::Clone for
ZeroTrieSimpleAscii<Store> {
#[inline]
fn clone(&self) -> ZeroTrieSimpleAscii<Store> {
ZeroTrieSimpleAscii {
store: ::core::clone::Clone::clone(&self.store),
}
}
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::marker::Copy + ?Sized> ::core::marker::Copy for
ZeroTrieSimpleAscii<Store> {
}Copy, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::PartialEq + ?Sized> ::core::cmp::PartialEq for
ZeroTrieSimpleAscii<Store> {
#[inline]
fn eq(&self, other: &ZeroTrieSimpleAscii<Store>) -> bool {
self.store == other.store
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::Eq + ?Sized> ::core::cmp::Eq for
ZeroTrieSimpleAscii<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Store>;
}
}Eq)]
115#[cfg_attr(feature = "databake", derive(databake::Bake))]
116#[cfg_attr(feature = "databake", databake(path = zerotrie))]
117#[allow(clippy::exhaustive_structs)] pub struct ZeroTrieSimpleAscii<Store: ?Sized> {
119 #[doc(hidden)] pub store: Store,
121}
122
123impl<Store: ?Sized> ZeroTrieSimpleAscii<Store> {
124 #[allow(unsafe_code)] fn transparent_ref_from_store(s: &Store) -> &Self {
126 unsafe {
127 &*(s as *const Store as *const Self)
129 }
130 }
131}
132
133impl<Store> ZeroTrieSimpleAscii<Store> {
134 #[inline]
136 pub const fn into_zerotrie(self) -> ZeroTrie<Store> {
137 ZeroTrie(ZeroTrieFlavor::SimpleAscii(self))
138 }
139}
140
141#[repr(transparent)]
182#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::fmt::Debug + ?Sized> ::core::fmt::Debug for
ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ZeroAsciiIgnoreCaseTrie", "store", &&self.store)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::default::Default + ?Sized> ::core::default::Default for
ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
fn default() -> ZeroAsciiIgnoreCaseTrie<Store> {
ZeroAsciiIgnoreCaseTrie { store: ::core::default::Default::default() }
}
}Default, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::clone::Clone + ?Sized> ::core::clone::Clone for
ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
fn clone(&self) -> ZeroAsciiIgnoreCaseTrie<Store> {
ZeroAsciiIgnoreCaseTrie {
store: ::core::clone::Clone::clone(&self.store),
}
}
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::marker::Copy + ?Sized> ::core::marker::Copy for
ZeroAsciiIgnoreCaseTrie<Store> {
}Copy, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::PartialEq + ?Sized> ::core::cmp::PartialEq for
ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
fn eq(&self, other: &ZeroAsciiIgnoreCaseTrie<Store>) -> bool {
self.store == other.store
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::Eq + ?Sized> ::core::cmp::Eq for
ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Store>;
}
}Eq)]
183#[cfg_attr(feature = "databake", derive(databake::Bake))]
184#[cfg_attr(feature = "databake", databake(path = zerotrie))]
185#[allow(clippy::exhaustive_structs)] pub struct ZeroAsciiIgnoreCaseTrie<Store: ?Sized> {
187 #[doc(hidden)] pub store: Store,
189}
190
191impl<Store: ?Sized> ZeroAsciiIgnoreCaseTrie<Store> {
192 #[allow(unsafe_code)] fn transparent_ref_from_store(s: &Store) -> &Self {
194 unsafe {
195 &*(s as *const Store as *const Self)
197 }
198 }
199}
200
201#[repr(transparent)]
228#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::fmt::Debug + ?Sized> ::core::fmt::Debug for
ZeroTriePerfectHash<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ZeroTriePerfectHash", "store", &&self.store)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::default::Default + ?Sized> ::core::default::Default for
ZeroTriePerfectHash<Store> {
#[inline]
fn default() -> ZeroTriePerfectHash<Store> {
ZeroTriePerfectHash { store: ::core::default::Default::default() }
}
}Default, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::clone::Clone + ?Sized> ::core::clone::Clone for
ZeroTriePerfectHash<Store> {
#[inline]
fn clone(&self) -> ZeroTriePerfectHash<Store> {
ZeroTriePerfectHash {
store: ::core::clone::Clone::clone(&self.store),
}
}
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::marker::Copy + ?Sized> ::core::marker::Copy for
ZeroTriePerfectHash<Store> {
}Copy, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::PartialEq + ?Sized> ::core::cmp::PartialEq for
ZeroTriePerfectHash<Store> {
#[inline]
fn eq(&self, other: &ZeroTriePerfectHash<Store>) -> bool {
self.store == other.store
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::Eq + ?Sized> ::core::cmp::Eq for
ZeroTriePerfectHash<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Store>;
}
}Eq)]
229#[cfg_attr(feature = "databake", derive(databake::Bake))]
230#[cfg_attr(feature = "databake", databake(path = zerotrie))]
231#[allow(clippy::exhaustive_structs)] pub struct ZeroTriePerfectHash<Store: ?Sized> {
233 #[doc(hidden)] pub store: Store,
235}
236
237impl<Store: ?Sized> ZeroTriePerfectHash<Store> {
238 #[allow(unsafe_code)] fn transparent_ref_from_store(s: &Store) -> &Self {
240 unsafe {
241 &*(s as *const Store as *const Self)
243 }
244 }
245}
246
247impl<Store> ZeroTriePerfectHash<Store> {
248 #[inline]
250 pub const fn into_zerotrie(self) -> ZeroTrie<Store> {
251 ZeroTrie(ZeroTrieFlavor::PerfectHash(self))
252 }
253}
254
255#[repr(transparent)]
259#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::fmt::Debug + ?Sized> ::core::fmt::Debug for
ZeroTrieExtendedCapacity<Store> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ZeroTrieExtendedCapacity", "store", &&self.store)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::default::Default + ?Sized> ::core::default::Default for
ZeroTrieExtendedCapacity<Store> {
#[inline]
fn default() -> ZeroTrieExtendedCapacity<Store> {
ZeroTrieExtendedCapacity {
store: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::clone::Clone + ?Sized> ::core::clone::Clone for
ZeroTrieExtendedCapacity<Store> {
#[inline]
fn clone(&self) -> ZeroTrieExtendedCapacity<Store> {
ZeroTrieExtendedCapacity {
store: ::core::clone::Clone::clone(&self.store),
}
}
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::marker::Copy + ?Sized> ::core::marker::Copy for
ZeroTrieExtendedCapacity<Store> {
}Copy, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::PartialEq + ?Sized> ::core::cmp::PartialEq for
ZeroTrieExtendedCapacity<Store> {
#[inline]
fn eq(&self, other: &ZeroTrieExtendedCapacity<Store>) -> bool {
self.store == other.store
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<Store: ::core::cmp::Eq + ?Sized> ::core::cmp::Eq for
ZeroTrieExtendedCapacity<Store> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Store>;
}
}Eq)]
260#[cfg_attr(feature = "databake", derive(databake::Bake))]
261#[cfg_attr(feature = "databake", databake(path = zerotrie))]
262#[allow(clippy::exhaustive_structs)] pub struct ZeroTrieExtendedCapacity<Store: ?Sized> {
264 #[doc(hidden)] pub store: Store,
266}
267
268impl<Store: ?Sized> ZeroTrieExtendedCapacity<Store> {
269 #[allow(unsafe_code)] fn transparent_ref_from_store(s: &Store) -> &Self {
271 unsafe {
272 &*(s as *const Store as *const Self)
274 }
275 }
276}
277
278impl<Store> ZeroTrieExtendedCapacity<Store> {
279 #[inline]
281 pub const fn into_zerotrie(self) -> ZeroTrie<Store> {
282 ZeroTrie(ZeroTrieFlavor::ExtendedCapacity(self))
283 }
284}
285
286macro_rules! impl_zerotrie_subtype {
287 ($name:ident, $iter_element:ty, $iter_fn:path, $iter_ty:ty, $cnv_fn:path) => {
288 impl<Store> $name<Store> {
289 #[inline]
293 pub const fn from_store(store: Store) -> Self {
294 Self { store }
295 }
296 #[inline]
298 pub fn into_store(self) -> Store {
299 self.store
300 }
301 #[doc = concat!("For example, use this to change `", stringify!($name), "<Vec<u8>>` to `", stringify!($name), "<Cow<[u8]>>`.")]
304 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
310 #[doc = concat!("let trie: ", stringify!($name), "<Vec<u8>> = ", stringify!($name), "::from_bytes(b\"abc\\x85\").to_owned();")]
312 #[doc = concat!("let cow: ", stringify!($name), "<Cow<[u8]>> = trie.convert_store();")]
313 pub fn convert_store<X: From<Store>>(self) -> $name<X> {
317 $name::<X>::from_store(X::from(self.store))
318 }
319 }
320 impl<Store> $name<Store>
321 where
322 Store: AsRef<[u8]> + ?Sized,
323 {
324 pub fn get<K>(&self, key: K) -> Option<usize> where K: AsRef<[u8]> {
328 reader::get_parameterized::<Self>(self.store.as_ref(), key.as_ref())
329 }
330 #[inline]
332 pub fn is_empty(&self) -> bool {
333 self.store.as_ref().is_empty()
334 }
335 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
341 #[doc = concat!("let trie: &", stringify!($name), "<[u8]> = ", stringify!($name), "::from_bytes(b\"abc\\x80def\\x81\");")]
344 #[inline]
349 pub fn byte_len(&self) -> usize {
350 self.store.as_ref().len()
351 }
352 #[inline]
354 pub fn as_bytes(&self) -> &[u8] {
355 self.store.as_ref()
356 }
357 #[inline]
359 pub fn as_borrowed(&self) -> &$name<[u8]> {
360 $name::from_bytes(self.store.as_ref())
361 }
362 #[inline]
364 pub fn as_borrowed_slice(&self) -> $name<&[u8]> {
365 $name::from_store(self.store.as_ref())
366 }
367 }
368 impl<Store> AsRef<$name<[u8]>> for $name<Store>
369 where
370 Store: AsRef<[u8]> + ?Sized,
371 {
372 #[inline]
373 fn as_ref(&self) -> &$name<[u8]> {
374 self.as_borrowed()
375 }
376 }
377 #[cfg(feature = "alloc")]
378 impl<Store> $name<Store>
379 where
380 Store: AsRef<[u8]> + ?Sized,
381 {
382 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
390 #[doc = concat!("let trie: &", stringify!($name), "<[u8]> = ", stringify!($name), "::from_bytes(b\"abc\\x85\");")]
392 #[doc = concat!("let owned: ", stringify!($name), "<Vec<u8>> = trie.to_owned();")]
393 #[inline]
398 pub fn to_owned(&self) -> $name<Vec<u8>> {
399 $name::from_store(
400 Vec::from(self.store.as_ref()),
401 )
402 }
403 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
411 #[doc = concat!("let trie: &", stringify!($name), "<[u8]> = ", stringify!($name), "::from_bytes(b\"abc\\x80def\\x81\");")]
414 #[inline]
421 pub fn iter(&self) -> $iter_ty {
422 $iter_fn(self.as_bytes())
423 }
424 }
425 impl $name<[u8]> {
426 #[inline]
430 pub fn from_bytes(trie: &[u8]) -> &Self {
431 Self::transparent_ref_from_store(trie)
432 }
433 }
434 #[cfg(feature = "alloc")]
435 impl $name<Vec<u8>> {
436 pub(crate) fn try_from_tuple_slice(items: ByteSliceWithIndices) -> Result<Self, ZeroTrieBuildError> {
437 use crate::options::ZeroTrieWithOptions;
438 ZeroTrieBuilder::<VecDeque<u8>>::from_sorted_tuple_slice(
439 items,
440 Self::OPTIONS,
441 )
442 .map(|s| Self {
443 store: s.to_bytes(),
444 })
445 }
446 pub fn try_from_btree_map_str<K>(items: &BTreeMap<K, usize>) -> Result<Self, ZeroTrieBuildError>
450 where
451 K: Borrow<str>
452 {
453 let tuples: Vec<(&[u8], usize)> = items
454 .iter()
455 .map(|(k, v)| (k.borrow().as_bytes(), *v))
456 .collect();
457 let byte_str_slice = ByteSliceWithIndices::from_byte_slice(&tuples);
458 Self::try_from_tuple_slice(byte_str_slice)
459 }
460 }
461 #[cfg(feature = "alloc")]
462 impl<K> FromIterator<(K, usize)> for $name<Vec<u8>>
463 where
464 K: AsRef<[u8]>
465 {
466 fn from_iter<T: IntoIterator<Item = (K, usize)>>(iter: T) -> Self {
467 use crate::options::ZeroTrieWithOptions;
468 use crate::builder::nonconst::ZeroTrieBuilder;
469 ZeroTrieBuilder::<VecDeque<u8>>::from_bytes_iter(
470 iter,
471 Self::OPTIONS
472 )
473 .map(|s| Self {
474 store: s.to_bytes(),
475 })
476 .unwrap()
477 }
478 }
479 #[cfg(feature = "alloc")]
480 impl<'a, K> TryFrom<&'a BTreeMap<K, usize>> for $name<Vec<u8>>
481 where
482 K: Borrow<[u8]>
483 {
484 type Error = crate::error::ZeroTrieBuildError;
485 fn try_from(map: &'a BTreeMap<K, usize>) -> Result<Self, Self::Error> {
486 let tuples: Vec<(&[u8], usize)> = map
487 .iter()
488 .map(|(k, v)| (k.borrow(), *v))
489 .collect();
490 let byte_str_slice = ByteSliceWithIndices::from_byte_slice(&tuples);
491 Self::try_from_tuple_slice(byte_str_slice)
492 }
493 }
494 #[cfg(feature = "alloc")]
495 impl<Store> $name<Store>
496 where
497 Store: AsRef<[u8]> + ?Sized
498 {
499 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
507 #[doc = concat!("let trie = ", stringify!($name), "::from_bytes(b\"abc\\x81def\\x82\");")]
510 #[doc = concat!("let recovered_trie: ", stringify!($name), "<Vec<u8>> = items")]
515 pub fn to_btreemap(&self) -> BTreeMap<$iter_element, usize> {
520 self.iter().collect()
521 }
522 #[allow(dead_code)] pub(crate) fn to_btreemap_bytes(&self) -> BTreeMap<Box<[u8]>, usize> {
524 self.iter().map(|(k, v)| ($cnv_fn(k), v)).collect()
525 }
526 }
527 #[cfg(feature = "alloc")]
528 impl<Store> From<&$name<Store>> for BTreeMap<$iter_element, usize>
529 where
530 Store: AsRef<[u8]> + ?Sized,
531 {
532 #[inline]
533 fn from(other: &$name<Store>) -> Self {
534 other.to_btreemap()
535 }
536 }
537 #[cfg(feature = "litemap")]
538 impl<'a, K, S> TryFrom<&'a LiteMap<K, usize, S>> for $name<Vec<u8>>
539 where
540 K: Borrow<[u8]>,
541 S: litemap::store::StoreIterable<'a, K, usize>,
542 {
543 type Error = crate::error::ZeroTrieBuildError;
544 fn try_from(map: &'a LiteMap<K, usize, S>) -> Result<Self, Self::Error> {
545 let tuples: Vec<(&[u8], usize)> = map
546 .iter()
547 .map(|(k, v)| (k.borrow(), *v))
548 .collect();
549 let byte_str_slice = ByteSliceWithIndices::from_byte_slice(&tuples);
550 Self::try_from_tuple_slice(byte_str_slice)
551 }
552 }
553 #[cfg(feature = "litemap")]
554 impl<Store> $name<Store>
555 where
556 Store: AsRef<[u8]> + ?Sized,
557 {
558 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
566 #[doc = concat!("let trie = ", stringify!($name), "::from_bytes(b\"abc\\x81def\\x82\");")]
569 #[doc = concat!("let recovered_trie: ", stringify!($name), "<Vec<u8>> = items")]
574 pub fn to_litemap(&self) -> LiteMap<$iter_element, usize> {
580 self.iter().collect()
581 }
582 #[allow(dead_code)] pub(crate) fn to_litemap_bytes(&self) -> LiteMap<Box<[u8]>, usize> {
584 self.iter().map(|(k, v)| ($cnv_fn(k), v)).collect()
585 }
586 #[cfg(feature = "serde")]
587 pub(crate) fn to_litemap_serde(&self) -> LiteMap<crate::serde::SerdeByteStrOwned, usize> {
588 self.iter().map(|(k, v)| (crate::serde::SerdeByteStrOwned($cnv_fn(k)), v)).collect()
589 }
590 }
591 #[cfg(feature = "litemap")]
592 impl<Store> From<&$name<Store>> for LiteMap<$iter_element, usize>
593 where
594 Store: AsRef<[u8]> + ?Sized,
595 {
596 #[inline]
597 fn from(other: &$name<Store>) -> Self {
598 other.to_litemap()
599 }
600 }
601 #[cfg(feature = "litemap")]
602 impl $name<Vec<u8>>
603 {
604 #[cfg(feature = "serde")]
605 pub(crate) fn try_from_serde_litemap(items: &LiteMap<crate::serde::SerdeByteStrOwned, usize>) -> Result<Self, ZeroTrieBuildError> {
606 let tuples: Vec<(&[u8], usize)> = items.iter().map(|(k, v)| (k.as_bytes(), *v)).collect();
607 let byte_str_slice = ByteSliceWithIndices::from_byte_slice(&tuples);
608 Self::try_from_tuple_slice(byte_str_slice)
609 }
610 }
611 impl Borrow<$name<[u8]>> for $name<&[u8]> {
613 #[inline]
614 fn borrow(&self) -> &$name<[u8]> {
615 self.as_borrowed()
616 }
617 }
618 #[cfg(feature = "alloc")]
620 impl Borrow<$name<[u8]>> for $name<Box<[u8]>> {
621 #[inline]
622 fn borrow(&self) -> &$name<[u8]> {
623 self.as_borrowed()
624 }
625 }
626 #[cfg(feature = "alloc")]
628 impl Borrow<$name<[u8]>> for $name<Vec<u8>> {
629 #[inline]
630 fn borrow(&self) -> &$name<[u8]> {
631 self.as_borrowed()
632 }
633 }
634 #[cfg(feature = "alloc")]
635 impl alloc::borrow::ToOwned for $name<[u8]> {
636 type Owned = $name<Box<[u8]>>;
637 #[doc = concat!("This impl allows [`", stringify!($name), "`] to be used inside of a [`Cow`](alloc::borrow::Cow).")]
638 #[doc = concat!("Note that it is also possible to use `", stringify!($name), "<ZeroVec<u8>>` for a similar result.")]
640 #[doc = concat!("use zerotrie::", stringify!($name), ";")]
648 #[doc = concat!("let trie: Cow<", stringify!($name), "<[u8]>> = Cow::Borrowed(", stringify!($name), "::from_bytes(b\"abc\\x85\"));")]
650 fn to_owned(&self) -> Self::Owned {
653 let bytes: &[u8] = self.store.as_ref();
654 $name::from_store(
655 Vec::from(bytes).into_boxed_slice(),
656 )
657 }
658 }
659 #[cfg(feature = "zerovec")]
671 #[allow(unsafe_code)] unsafe impl<Store> zerovec::ule::VarULE for $name<Store>
673 where
674 Store: zerovec::ule::VarULE,
675 {
676 #[inline]
677 fn validate_bytes(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> {
678 Store::validate_bytes(bytes)
679 }
680 #[inline]
681 unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
682 Self::transparent_ref_from_store(Store::from_bytes_unchecked(bytes))
684 }
685 }
686 #[cfg(feature = "zerofrom")]
687 impl<'zf, Store1, Store2> zerofrom::ZeroFrom<'zf, $name<Store1>> for $name<Store2>
688 where
689 Store2: zerofrom::ZeroFrom<'zf, Store1>,
690 {
691 #[inline]
692 fn zero_from(other: &'zf $name<Store1>) -> Self {
693 $name::from_store(zerofrom::ZeroFrom::zero_from(&other.store))
694 }
695 }
696 };
697}
698
699#[cfg(feature = "alloc")]
700fn string_to_box_u8(input: String) -> Box<[u8]> {
701 input.into_boxed_str().into_boxed_bytes()
702}
703
704#[doc(hidden)] #[cfg(feature = "alloc")]
706pub type ZeroTrieStringIterator<'a> =
707 core::iter::Map<reader::ZeroTrieIterator<'a>, fn((Vec<u8>, usize)) -> (String, usize)>;
708
709impl<Store> ZeroTrieSimpleAscii<Store> {
#[inline]
pub const fn from_store(store: Store) -> Self { Self { store } }
#[inline]
pub fn into_store(self) -> Store { self.store }
#[doc =
"For example, use this to change `ZeroTrieSimpleAscii<Vec<u8>>` to `ZeroTrieSimpleAscii<Cow<[u8]>>`."]
#[doc = "use zerotrie::ZeroTrieSimpleAscii;"]
#[doc =
"let trie: ZeroTrieSimpleAscii<Vec<u8>> = ZeroTrieSimpleAscii::from_bytes(b\"abc\\x85\").to_owned();"]
#[doc = "let cow: ZeroTrieSimpleAscii<Cow<[u8]>> = trie.convert_store();"]
pub fn convert_store<X: From<Store>>(self) -> ZeroTrieSimpleAscii<X> {
ZeroTrieSimpleAscii::<X>::from_store(X::from(self.store))
}
}
impl<Store> ZeroTrieSimpleAscii<Store> where Store: AsRef<[u8]> + ?Sized {
pub fn get<K>(&self, key: K) -> Option<usize> where K: AsRef<[u8]> {
reader::get_parameterized::<Self>(self.store.as_ref(), key.as_ref())
}
#[inline]
pub fn is_empty(&self) -> bool { self.store.as_ref().is_empty() }
#[doc = "use zerotrie::ZeroTrieSimpleAscii;"]
#[doc =
"let trie: &ZeroTrieSimpleAscii<[u8]> = ZeroTrieSimpleAscii::from_bytes(b\"abc\\x80def\\x81\");"]
#[inline]
pub fn byte_len(&self) -> usize { self.store.as_ref().len() }
#[inline]
pub fn as_bytes(&self) -> &[u8] { self.store.as_ref() }
#[inline]
pub fn as_borrowed(&self) -> &ZeroTrieSimpleAscii<[u8]> {
ZeroTrieSimpleAscii::from_bytes(self.store.as_ref())
}
#[inline]
pub fn as_borrowed_slice(&self) -> ZeroTrieSimpleAscii<&[u8]> {
ZeroTrieSimpleAscii::from_store(self.store.as_ref())
}
}
impl<Store> AsRef<ZeroTrieSimpleAscii<[u8]>> for ZeroTrieSimpleAscii<Store>
where Store: AsRef<[u8]> + ?Sized {
#[inline]
fn as_ref(&self) -> &ZeroTrieSimpleAscii<[u8]> { self.as_borrowed() }
}
impl ZeroTrieSimpleAscii<[u8]> {
#[inline]
pub fn from_bytes(trie: &[u8]) -> &Self {
Self::transparent_ref_from_store(trie)
}
}
impl Borrow<ZeroTrieSimpleAscii<[u8]>> for ZeroTrieSimpleAscii<&[u8]> {
#[inline]
fn borrow(&self) -> &ZeroTrieSimpleAscii<[u8]> { self.as_borrowed() }
}
impl<'zf, Store1, Store2> zerofrom::ZeroFrom<'zf, ZeroTrieSimpleAscii<Store1>>
for ZeroTrieSimpleAscii<Store2> where
Store2: zerofrom::ZeroFrom<'zf, Store1> {
#[inline]
fn zero_from(other: &'zf ZeroTrieSimpleAscii<Store1>) -> Self {
ZeroTrieSimpleAscii::from_store(zerofrom::ZeroFrom::zero_from(&other.store))
}
}impl_zerotrie_subtype!(
710 ZeroTrieSimpleAscii,
711 String,
712 reader::get_iter_ascii_or_panic,
713 ZeroTrieStringIterator<'_>,
714 string_to_box_u8
715);
716impl<Store> ZeroAsciiIgnoreCaseTrie<Store> {
#[inline]
pub const fn from_store(store: Store) -> Self { Self { store } }
#[inline]
pub fn into_store(self) -> Store { self.store }
#[doc =
"For example, use this to change `ZeroAsciiIgnoreCaseTrie<Vec<u8>>` to `ZeroAsciiIgnoreCaseTrie<Cow<[u8]>>`."]
#[doc = "use zerotrie::ZeroAsciiIgnoreCaseTrie;"]
#[doc =
"let trie: ZeroAsciiIgnoreCaseTrie<Vec<u8>> = ZeroAsciiIgnoreCaseTrie::from_bytes(b\"abc\\x85\").to_owned();"]
#[doc =
"let cow: ZeroAsciiIgnoreCaseTrie<Cow<[u8]>> = trie.convert_store();"]
pub fn convert_store<X: From<Store>>(self) -> ZeroAsciiIgnoreCaseTrie<X> {
ZeroAsciiIgnoreCaseTrie::<X>::from_store(X::from(self.store))
}
}
impl<Store> ZeroAsciiIgnoreCaseTrie<Store> where Store: AsRef<[u8]> + ?Sized {
pub fn get<K>(&self, key: K) -> Option<usize> where K: AsRef<[u8]> {
reader::get_parameterized::<Self>(self.store.as_ref(), key.as_ref())
}
#[inline]
pub fn is_empty(&self) -> bool { self.store.as_ref().is_empty() }
#[doc = "use zerotrie::ZeroAsciiIgnoreCaseTrie;"]
#[doc =
"let trie: &ZeroAsciiIgnoreCaseTrie<[u8]> = ZeroAsciiIgnoreCaseTrie::from_bytes(b\"abc\\x80def\\x81\");"]
#[inline]
pub fn byte_len(&self) -> usize { self.store.as_ref().len() }
#[inline]
pub fn as_bytes(&self) -> &[u8] { self.store.as_ref() }
#[inline]
pub fn as_borrowed(&self) -> &ZeroAsciiIgnoreCaseTrie<[u8]> {
ZeroAsciiIgnoreCaseTrie::from_bytes(self.store.as_ref())
}
#[inline]
pub fn as_borrowed_slice(&self) -> ZeroAsciiIgnoreCaseTrie<&[u8]> {
ZeroAsciiIgnoreCaseTrie::from_store(self.store.as_ref())
}
}
impl<Store> AsRef<ZeroAsciiIgnoreCaseTrie<[u8]>> for
ZeroAsciiIgnoreCaseTrie<Store> where Store: AsRef<[u8]> + ?Sized {
#[inline]
fn as_ref(&self) -> &ZeroAsciiIgnoreCaseTrie<[u8]> { self.as_borrowed() }
}
impl ZeroAsciiIgnoreCaseTrie<[u8]> {
#[inline]
pub fn from_bytes(trie: &[u8]) -> &Self {
Self::transparent_ref_from_store(trie)
}
}
impl Borrow<ZeroAsciiIgnoreCaseTrie<[u8]>> for ZeroAsciiIgnoreCaseTrie<&[u8]>
{
#[inline]
fn borrow(&self) -> &ZeroAsciiIgnoreCaseTrie<[u8]> { self.as_borrowed() }
}
impl<'zf, Store1, Store2>
zerofrom::ZeroFrom<'zf, ZeroAsciiIgnoreCaseTrie<Store1>> for
ZeroAsciiIgnoreCaseTrie<Store2> where
Store2: zerofrom::ZeroFrom<'zf, Store1> {
#[inline]
fn zero_from(other: &'zf ZeroAsciiIgnoreCaseTrie<Store1>) -> Self {
ZeroAsciiIgnoreCaseTrie::from_store(zerofrom::ZeroFrom::zero_from(&other.store))
}
}impl_zerotrie_subtype!(
717 ZeroAsciiIgnoreCaseTrie,
718 String,
719 reader::get_iter_ascii_or_panic,
720 ZeroTrieStringIterator<'_>,
721 string_to_box_u8
722);
723impl<Store> ZeroTriePerfectHash<Store> {
#[inline]
pub const fn from_store(store: Store) -> Self { Self { store } }
#[inline]
pub fn into_store(self) -> Store { self.store }
#[doc =
"For example, use this to change `ZeroTriePerfectHash<Vec<u8>>` to `ZeroTriePerfectHash<Cow<[u8]>>`."]
#[doc = "use zerotrie::ZeroTriePerfectHash;"]
#[doc =
"let trie: ZeroTriePerfectHash<Vec<u8>> = ZeroTriePerfectHash::from_bytes(b\"abc\\x85\").to_owned();"]
#[doc = "let cow: ZeroTriePerfectHash<Cow<[u8]>> = trie.convert_store();"]
pub fn convert_store<X: From<Store>>(self) -> ZeroTriePerfectHash<X> {
ZeroTriePerfectHash::<X>::from_store(X::from(self.store))
}
}
impl<Store> ZeroTriePerfectHash<Store> where Store: AsRef<[u8]> + ?Sized {
pub fn get<K>(&self, key: K) -> Option<usize> where K: AsRef<[u8]> {
reader::get_parameterized::<Self>(self.store.as_ref(), key.as_ref())
}
#[inline]
pub fn is_empty(&self) -> bool { self.store.as_ref().is_empty() }
#[doc = "use zerotrie::ZeroTriePerfectHash;"]
#[doc =
"let trie: &ZeroTriePerfectHash<[u8]> = ZeroTriePerfectHash::from_bytes(b\"abc\\x80def\\x81\");"]
#[inline]
pub fn byte_len(&self) -> usize { self.store.as_ref().len() }
#[inline]
pub fn as_bytes(&self) -> &[u8] { self.store.as_ref() }
#[inline]
pub fn as_borrowed(&self) -> &ZeroTriePerfectHash<[u8]> {
ZeroTriePerfectHash::from_bytes(self.store.as_ref())
}
#[inline]
pub fn as_borrowed_slice(&self) -> ZeroTriePerfectHash<&[u8]> {
ZeroTriePerfectHash::from_store(self.store.as_ref())
}
}
impl<Store> AsRef<ZeroTriePerfectHash<[u8]>> for ZeroTriePerfectHash<Store>
where Store: AsRef<[u8]> + ?Sized {
#[inline]
fn as_ref(&self) -> &ZeroTriePerfectHash<[u8]> { self.as_borrowed() }
}
impl ZeroTriePerfectHash<[u8]> {
#[inline]
pub fn from_bytes(trie: &[u8]) -> &Self {
Self::transparent_ref_from_store(trie)
}
}
impl Borrow<ZeroTriePerfectHash<[u8]>> for ZeroTriePerfectHash<&[u8]> {
#[inline]
fn borrow(&self) -> &ZeroTriePerfectHash<[u8]> { self.as_borrowed() }
}
impl<'zf, Store1, Store2> zerofrom::ZeroFrom<'zf, ZeroTriePerfectHash<Store1>>
for ZeroTriePerfectHash<Store2> where
Store2: zerofrom::ZeroFrom<'zf, Store1> {
#[inline]
fn zero_from(other: &'zf ZeroTriePerfectHash<Store1>) -> Self {
ZeroTriePerfectHash::from_store(zerofrom::ZeroFrom::zero_from(&other.store))
}
}impl_zerotrie_subtype!(
724 ZeroTriePerfectHash,
725 Vec<u8>,
726 reader::get_iter_phf,
727 reader::ZeroTrieIterator<'_>,
728 Vec::into_boxed_slice
729);
730impl<Store> ZeroTrieExtendedCapacity<Store> {
#[inline]
pub const fn from_store(store: Store) -> Self { Self { store } }
#[inline]
pub fn into_store(self) -> Store { self.store }
#[doc =
"For example, use this to change `ZeroTrieExtendedCapacity<Vec<u8>>` to `ZeroTrieExtendedCapacity<Cow<[u8]>>`."]
#[doc = "use zerotrie::ZeroTrieExtendedCapacity;"]
#[doc =
"let trie: ZeroTrieExtendedCapacity<Vec<u8>> = ZeroTrieExtendedCapacity::from_bytes(b\"abc\\x85\").to_owned();"]
#[doc =
"let cow: ZeroTrieExtendedCapacity<Cow<[u8]>> = trie.convert_store();"]
pub fn convert_store<X: From<Store>>(self)
-> ZeroTrieExtendedCapacity<X> {
ZeroTrieExtendedCapacity::<X>::from_store(X::from(self.store))
}
}
impl<Store> ZeroTrieExtendedCapacity<Store> where Store: AsRef<[u8]> + ?Sized
{
pub fn get<K>(&self, key: K) -> Option<usize> where K: AsRef<[u8]> {
reader::get_parameterized::<Self>(self.store.as_ref(), key.as_ref())
}
#[inline]
pub fn is_empty(&self) -> bool { self.store.as_ref().is_empty() }
#[doc = "use zerotrie::ZeroTrieExtendedCapacity;"]
#[doc =
"let trie: &ZeroTrieExtendedCapacity<[u8]> = ZeroTrieExtendedCapacity::from_bytes(b\"abc\\x80def\\x81\");"]
#[inline]
pub fn byte_len(&self) -> usize { self.store.as_ref().len() }
#[inline]
pub fn as_bytes(&self) -> &[u8] { self.store.as_ref() }
#[inline]
pub fn as_borrowed(&self) -> &ZeroTrieExtendedCapacity<[u8]> {
ZeroTrieExtendedCapacity::from_bytes(self.store.as_ref())
}
#[inline]
pub fn as_borrowed_slice(&self) -> ZeroTrieExtendedCapacity<&[u8]> {
ZeroTrieExtendedCapacity::from_store(self.store.as_ref())
}
}
impl<Store> AsRef<ZeroTrieExtendedCapacity<[u8]>> for
ZeroTrieExtendedCapacity<Store> where Store: AsRef<[u8]> + ?Sized {
#[inline]
fn as_ref(&self) -> &ZeroTrieExtendedCapacity<[u8]> { self.as_borrowed() }
}
impl ZeroTrieExtendedCapacity<[u8]> {
#[inline]
pub fn from_bytes(trie: &[u8]) -> &Self {
Self::transparent_ref_from_store(trie)
}
}
impl Borrow<ZeroTrieExtendedCapacity<[u8]>> for
ZeroTrieExtendedCapacity<&[u8]> {
#[inline]
fn borrow(&self) -> &ZeroTrieExtendedCapacity<[u8]> { self.as_borrowed() }
}
impl<'zf, Store1, Store2>
zerofrom::ZeroFrom<'zf, ZeroTrieExtendedCapacity<Store1>> for
ZeroTrieExtendedCapacity<Store2> where
Store2: zerofrom::ZeroFrom<'zf, Store1> {
#[inline]
fn zero_from(other: &'zf ZeroTrieExtendedCapacity<Store1>) -> Self {
ZeroTrieExtendedCapacity::from_store(zerofrom::ZeroFrom::zero_from(&other.store))
}
}impl_zerotrie_subtype!(
731 ZeroTrieExtendedCapacity,
732 Vec<u8>,
733 reader::get_iter_phf,
734 reader::ZeroTrieIterator<'_>,
735 Vec::into_boxed_slice
736);
737
738#[allow(unused_macro_rules)] macro_rules! impl_dispatch {
740 ($self:ident, $inner_fn:ident()) => {
741 match $self.0 {
742 ZeroTrieFlavor::SimpleAscii(subtype) => subtype.$inner_fn(),
743 ZeroTrieFlavor::PerfectHash(subtype) => subtype.$inner_fn(),
744 ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.$inner_fn(),
745 }
746 };
747 ($self:ident, $inner_fn:ident().into_zerotrie()) => {
748 match $self.0 {
749 ZeroTrieFlavor::SimpleAscii(subtype) => subtype.$inner_fn().into_zerotrie(),
750 ZeroTrieFlavor::PerfectHash(subtype) => subtype.$inner_fn().into_zerotrie(),
751 ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.$inner_fn().into_zerotrie(),
752 }
753 };
754 (&$self:ident, $inner_fn:ident()) => {
755 match &$self.0 {
756 ZeroTrieFlavor::SimpleAscii(subtype) => subtype.$inner_fn(),
757 ZeroTrieFlavor::PerfectHash(subtype) => subtype.$inner_fn(),
758 ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.$inner_fn(),
759 }
760 };
761 (&$self:ident, $inner_fn:ident($arg:ident)) => {
762 match &$self.0 {
763 ZeroTrieFlavor::SimpleAscii(subtype) => subtype.$inner_fn($arg),
764 ZeroTrieFlavor::PerfectHash(subtype) => subtype.$inner_fn($arg),
765 ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.$inner_fn($arg),
766 }
767 };
768 (&$self:ident, $trait:ident::$inner_fn:ident()) => {
769 match &$self.0 {
770 ZeroTrieFlavor::SimpleAscii(subtype) => {
771 ZeroTrie(ZeroTrieFlavor::SimpleAscii($trait::$inner_fn(subtype)))
772 }
773 ZeroTrieFlavor::PerfectHash(subtype) => {
774 ZeroTrie(ZeroTrieFlavor::PerfectHash($trait::$inner_fn(subtype)))
775 }
776 ZeroTrieFlavor::ExtendedCapacity(subtype) => {
777 ZeroTrie(ZeroTrieFlavor::ExtendedCapacity($trait::$inner_fn(subtype)))
778 }
779 }
780 };
781}
782
783impl<Store> ZeroTrie<Store> {
784 pub fn into_store(self) -> Store {
786 match self.0 {
ZeroTrieFlavor::SimpleAscii(subtype) => subtype.into_store(),
ZeroTrieFlavor::PerfectHash(subtype) => subtype.into_store(),
ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.into_store(),
}impl_dispatch!(self, into_store())
787 }
788 pub fn convert_store<NewStore>(self) -> ZeroTrie<NewStore>
792 where
793 NewStore: From<Store>,
794 {
795 match self.0 {
ZeroTrieFlavor::SimpleAscii(subtype) =>
subtype.convert_store().into_zerotrie(),
ZeroTrieFlavor::PerfectHash(subtype) =>
subtype.convert_store().into_zerotrie(),
ZeroTrieFlavor::ExtendedCapacity(subtype) =>
subtype.convert_store().into_zerotrie(),
}impl_dispatch!(self, convert_store().into_zerotrie())
796 }
797}
798
799impl<Store> ZeroTrie<Store>
800where
801 Store: AsRef<[u8]>,
802{
803 pub fn get<K>(&self, key: K) -> Option<usize>
805 where
806 K: AsRef<[u8]>,
807 {
808 match &self.0 {
ZeroTrieFlavor::SimpleAscii(subtype) => subtype.get(key),
ZeroTrieFlavor::PerfectHash(subtype) => subtype.get(key),
ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.get(key),
}impl_dispatch!(&self, get(key))
809 }
810 pub fn is_empty(&self) -> bool {
812 match &self.0 {
ZeroTrieFlavor::SimpleAscii(subtype) => subtype.is_empty(),
ZeroTrieFlavor::PerfectHash(subtype) => subtype.is_empty(),
ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.is_empty(),
}impl_dispatch!(&self, is_empty())
813 }
814 pub fn byte_len(&self) -> usize {
818 match &self.0 {
ZeroTrieFlavor::SimpleAscii(subtype) => subtype.byte_len(),
ZeroTrieFlavor::PerfectHash(subtype) => subtype.byte_len(),
ZeroTrieFlavor::ExtendedCapacity(subtype) => subtype.byte_len(),
}impl_dispatch!(&self, byte_len())
819 }
820}
821
822#[cfg(feature = "alloc")]
823impl<Store> ZeroTrie<Store>
824where
825 Store: AsRef<[u8]>,
826{
827 pub fn to_btreemap(&self) -> BTreeMap<Box<[u8]>, usize> {
831 impl_dispatch!(&self, to_btreemap_bytes())
832 }
833}
834
835#[cfg(feature = "litemap")]
836impl<Store> ZeroTrie<Store>
837where
838 Store: AsRef<[u8]>,
839{
840 #[cfg(feature = "serde")]
842 pub fn to_litemap(&self) -> LiteMap<Box<[u8]>, usize> {
843 impl_dispatch!(&self, to_litemap_bytes())
844 }
845
846 #[cfg(feature = "serde")]
848 pub(crate) fn to_litemap_serde(&self) -> LiteMap<crate::serde::SerdeByteStrOwned, usize> {
849 impl_dispatch!(&self, to_litemap_serde())
850 }
851}
852#[cfg(feature = "alloc")]
853impl ZeroTrie<Vec<u8>> {
854 pub(crate) fn try_from_tuple_slice(
855 items: ByteSliceWithIndices,
856 ) -> Result<Self, ZeroTrieBuildError> {
857 let is_all_ascii = items.is_all_ascii();
858 if is_all_ascii && items.len() < 512 {
859 ZeroTrieSimpleAscii::try_from_tuple_slice(items).map(|x| x.into_zerotrie())
860 } else {
861 ZeroTriePerfectHash::try_from_tuple_slice(items).map(|x| x.into_zerotrie())
862 }
863 }
864}
865
866#[cfg(feature = "alloc")]
867impl<K> FromIterator<(K, usize)> for ZeroTrie<Vec<u8>>
868where
869 K: AsRef<[u8]>,
870{
871 fn from_iter<T: IntoIterator<Item = (K, usize)>>(iter: T) -> Self {
872 let items = Vec::from_iter(iter);
874 let mut items: Vec<(&[u8], usize)> = items.iter().map(|(k, v)| (k.as_ref(), *v)).collect();
875 items.sort();
876 let byte_str_slice = ByteSliceWithIndices::from_byte_slice(&items);
877 #[expect(clippy::unwrap_used)] Self::try_from_tuple_slice(byte_str_slice).unwrap()
879 }
880}
881
882#[cfg(feature = "databake")]
883impl<Store> databake::Bake for ZeroTrie<Store>
884where
885 Store: databake::Bake,
886{
887 fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream {
888 use databake::*;
889 let inner = impl_dispatch!(&self, bake(env));
890 quote! { #inner.into_zerotrie() }
891 }
892}
893
894#[cfg(feature = "databake")]
895impl<Store> databake::BakeSize for ZeroTrie<Store>
896where
897 Store: databake::BakeSize,
898{
899 fn borrows_size(&self) -> usize {
900 impl_dispatch!(&self, borrows_size())
901 }
902}
903
904#[cfg(feature = "zerofrom")]
905impl<'zf, Store1, Store2> zerofrom::ZeroFrom<'zf, ZeroTrie<Store1>> for ZeroTrie<Store2>
906where
907 Store2: zerofrom::ZeroFrom<'zf, Store1>,
908{
909 fn zero_from(other: &'zf ZeroTrie<Store1>) -> Self {
910 use zerofrom::ZeroFrom;
911 match &other.0 {
ZeroTrieFlavor::SimpleAscii(subtype) => {
ZeroTrie(ZeroTrieFlavor::SimpleAscii(ZeroFrom::zero_from(subtype)))
}
ZeroTrieFlavor::PerfectHash(subtype) => {
ZeroTrie(ZeroTrieFlavor::PerfectHash(ZeroFrom::zero_from(subtype)))
}
ZeroTrieFlavor::ExtendedCapacity(subtype) => {
ZeroTrie(ZeroTrieFlavor::ExtendedCapacity(ZeroFrom::zero_from(subtype)))
}
}impl_dispatch!(&other, ZeroFrom::zero_from())
912 }
913}