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 ).
45use super::vecs::{MutableZeroVecLike, ZeroVecLike};
6use crate::ule::*;
7use crate::vecs::{VarZeroSlice, VarZeroVec};
8use crate::zerovec::{ZeroSlice, ZeroVec};
9use alloc::boxed::Box;
1011/// 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`].
20type Container: MutableZeroVecLike<
21'a,
22Self,
23 SliceVariant = Self::Slice,
24 GetType = Self::GetType,
25 OwnedType = Self::OwnedType,
26 > + Sized;
27type 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`
32type 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>`
40type OwnedType: 'static;
41}
4243macro_rules! impl_sized_kv {
44 ($ty:path) => {
45impl<'a> ZeroMapKV<'a> for $ty {
46type Container = ZeroVec<'a, $ty>;
47type Slice = ZeroSlice<$ty>;
48type GetType = <$ty as AsULE>::ULE;
49type OwnedType = $ty;
50 }
51 };
52}
5354impl_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);
6768impl_sized_kv!(core::num::NonZeroU8);
69impl_sized_kv!(core::num::NonZeroI8);
7071impl<'a, T> ZeroMapKV<'a> for Option<T>
72where
73Option<T>: AsULE + 'static,
74{
75type Container = ZeroVec<'a, Option<T>>;
76type Slice = ZeroSlice<Option<T>>;
77type GetType = <Option<T> as AsULE>::ULE;
78type OwnedType = Option<T>;
79}
8081impl<'a, T> ZeroMapKV<'a> for OptionVarULE<T>
82where
83T: VarULE + ?Sized,
84{
85type Container = VarZeroVec<'a, OptionVarULE<T>>;
86type Slice = VarZeroSlice<OptionVarULE<T>>;
87type GetType = OptionVarULE<T>;
88type OwnedType = Box<OptionVarULE<T>>;
89}
9091impl<'a> ZeroMapKV<'a> for str {
92type Container = VarZeroVec<'a, str>;
93type Slice = VarZeroSlice<str>;
94type GetType = str;
95type OwnedType = Box<str>;
96}
9798impl<'a, T> ZeroMapKV<'a> for [T]
99where
100T: ULE + AsULE<ULE = T>,
101{
102type Container = VarZeroVec<'a, [T]>;
103type Slice = VarZeroSlice<[T]>;
104type GetType = [T];
105type OwnedType = Box<[T]>;
106}
107108impl<'a, T, const N: usize> ZeroMapKV<'a> for [T; N]
109where
110T: AsULE + 'static,
111{
112type Container = ZeroVec<'a, [T; N]>;
113type Slice = ZeroSlice<[T; N]>;
114type GetType = [T::ULE; N];
115type OwnedType = [T; N];
116}
117118impl<'a, T> ZeroMapKV<'a> for ZeroSlice<T>
119where
120T: AsULE + 'static,
121{
122type Container = VarZeroVec<'a, ZeroSlice<T>>;
123type Slice = VarZeroSlice<ZeroSlice<T>>;
124type GetType = ZeroSlice<T>;
125type OwnedType = Box<ZeroSlice<T>>;
126}