zerovec/map/
kv.rs

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