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::{VarZeroSlice, VarZeroVec};
8use crate::zerovec::{ZeroSlice, ZeroVec};
9use 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
18pub 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
43macro_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
54impl_sized_kv!(u8);
55impl_sized_kv!(u16);
56impl_sized_kv!(u32);
57impl_sized_kv!(u64);
58impl_sized_kv!(u128);
59impl_sized_kv!(i8);
60impl_sized_kv!(i16);
61impl_sized_kv!(i32);
62impl_sized_kv!(i64);
63impl_sized_kv!(i128);
64impl_sized_kv!(char);
65impl_sized_kv!(f32);
66impl_sized_kv!(f64);
67
68impl_sized_kv!(core::num::NonZeroU8);
69impl_sized_kv!(core::num::NonZeroI8);
70
71impl<'a, T> ZeroMapKV<'a> for Option<T>
72where
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
81impl<'a, T> ZeroMapKV<'a> for OptionVarULE<T>
82where
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
91impl<'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
98impl<'a, T> ZeroMapKV<'a> for [T]
99where
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
108impl<'a, T, const N: usize> ZeroMapKV<'a> for [T; N]
109where
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
118impl<'a, T> ZeroMapKV<'a> for ZeroSlice<T>
119where
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}