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::vecs::{MutableZeroVecLike, ZeroVecLike}; 6 use crate::ule::*; 7 use crate::vecs::{VarZeroSlice, VarZeroVec}; 8 use crate::zerovec::{ZeroSlice, ZeroVec}; 9 use alloc::boxed::Box; 10 11 /// Trait marking types which are allowed to be keys or values in [`ZeroMap`](super::ZeroMap). 12 /// 13 /// Users should not be calling methods of this trait directly, however if you are 14 /// implementing your own [`AsULE`] or [`VarULE`] type you may wish to implement 15 /// this trait. 16 // this lifetime should be a GAT on Container once that is possible 17 #[allow(clippy::upper_case_acronyms)] // KV is not an acronym 18 pub trait ZeroMapKV<'a> { 19 /// The container that can be used with this type: [`ZeroVec`] or [`VarZeroVec`]. 20 type Container: MutableZeroVecLike< 21 'a, 22 Self, 23 SliceVariant = Self::Slice, 24 GetType = Self::GetType, 25 OwnedType = Self::OwnedType, 26 > + Sized; 27 type Slice: ZeroVecLike<Self, GetType = Self::GetType> + ?Sized; 28 /// The type produced by `Container::get()` 29 /// 30 /// This type will be predetermined by the choice of `Self::Container`: 31 /// For sized types this must be `T::ULE`, and for unsized types this must be `T` 32 type GetType: ?Sized + 'static; 33 /// The type produced by `Container::replace()` and `Container::remove()`, 34 /// also used during deserialization. If `Self` is human readable serialized, 35 /// deserializing to `Self::OwnedType` should produce the same value once 36 /// passed through `Self::owned_as_self()` 37 /// 38 /// This type will be predetermined by the choice of `Self::Container`: 39 /// For sized types this must be `T` and for unsized types this must be `Box<T>` 40 type OwnedType: 'static; 41 } 42 43 macro_rules! impl_sized_kv { 44 ($ty:path) => { 45 impl<'a> ZeroMapKV<'a> for $ty { 46 type Container = ZeroVec<'a, $ty>; 47 type Slice = ZeroSlice<$ty>; 48 type GetType = <$ty as AsULE>::ULE; 49 type OwnedType = $ty; 50 } 51 }; 52 } 53 54 impl_sized_kv!(u8); 55 impl_sized_kv!(u16); 56 impl_sized_kv!(u32); 57 impl_sized_kv!(u64); 58 impl_sized_kv!(u128); 59 impl_sized_kv!(i8); 60 impl_sized_kv!(i16); 61 impl_sized_kv!(i32); 62 impl_sized_kv!(i64); 63 impl_sized_kv!(i128); 64 impl_sized_kv!(char); 65 impl_sized_kv!(f32); 66 impl_sized_kv!(f64); 67 68 impl_sized_kv!(core::num::NonZeroU8); 69 impl_sized_kv!(core::num::NonZeroI8); 70 71 impl<'a, T> ZeroMapKV<'a> for Option<T> 72 where 73 Option<T>: AsULE + 'static, 74 { 75 type Container = ZeroVec<'a, Option<T>>; 76 type Slice = ZeroSlice<Option<T>>; 77 type GetType = <Option<T> as AsULE>::ULE; 78 type OwnedType = Option<T>; 79 } 80 81 impl<'a, T> ZeroMapKV<'a> for OptionVarULE<T> 82 where 83 T: VarULE + ?Sized, 84 { 85 type Container = VarZeroVec<'a, OptionVarULE<T>>; 86 type Slice = VarZeroSlice<OptionVarULE<T>>; 87 type GetType = OptionVarULE<T>; 88 type OwnedType = Box<OptionVarULE<T>>; 89 } 90 91 impl<'a> ZeroMapKV<'a> for str { 92 type Container = VarZeroVec<'a, str>; 93 type Slice = VarZeroSlice<str>; 94 type GetType = str; 95 type OwnedType = Box<str>; 96 } 97 98 impl<'a, T> ZeroMapKV<'a> for [T] 99 where 100 T: ULE + AsULE<ULE = T>, 101 { 102 type Container = VarZeroVec<'a, [T]>; 103 type Slice = VarZeroSlice<[T]>; 104 type GetType = [T]; 105 type OwnedType = Box<[T]>; 106 } 107 108 impl<'a, T, const N: usize> ZeroMapKV<'a> for [T; N] 109 where 110 T: AsULE + 'static, 111 { 112 type Container = ZeroVec<'a, [T; N]>; 113 type Slice = ZeroSlice<[T; N]>; 114 type GetType = [T::ULE; N]; 115 type OwnedType = [T; N]; 116 } 117 118 impl<'a, T> ZeroMapKV<'a> for ZeroSlice<T> 119 where 120 T: AsULE + 'static, 121 { 122 type Container = VarZeroVec<'a, ZeroSlice<T>>; 123 type Slice = VarZeroSlice<ZeroSlice<T>>; 124 type GetType = ZeroSlice<T>; 125 type OwnedType = Box<ZeroSlice<T>>; 126 } 127