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::{FlexZeroSlice, FlexZeroVec}; |
8 | use crate::vecs::{VarZeroSlice, VarZeroVec}; |
9 | use crate::zerovec::{ZeroSlice, ZeroVec}; |
10 | use 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 |
19 | pub 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 | |
44 | macro_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 | |
55 | impl_sized_kv!(u8); |
56 | impl_sized_kv!(u16); |
57 | impl_sized_kv!(u32); |
58 | impl_sized_kv!(u64); |
59 | impl_sized_kv!(u128); |
60 | impl_sized_kv!(i8); |
61 | impl_sized_kv!(i16); |
62 | impl_sized_kv!(i32); |
63 | impl_sized_kv!(i64); |
64 | impl_sized_kv!(i128); |
65 | impl_sized_kv!(char); |
66 | impl_sized_kv!(f32); |
67 | impl_sized_kv!(f64); |
68 | |
69 | impl<'a> ZeroMapKV<'a> for usize { |
70 | type Container = FlexZeroVec<'a>; |
71 | type Slice = FlexZeroSlice; |
72 | type GetType = [u8]; |
73 | type OwnedType = usize; |
74 | } |
75 | |
76 | impl<'a, T> ZeroMapKV<'a> for Option<T> |
77 | where |
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 | |
86 | impl<'a, T> ZeroMapKV<'a> for OptionVarULE<T> |
87 | where |
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 | |
96 | impl<'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 | |
103 | impl<'a, T> ZeroMapKV<'a> for [T] |
104 | where |
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 | |
113 | impl<'a, T, const N: usize> ZeroMapKV<'a> for [T; N] |
114 | where |
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 | |
123 | impl<'a, T> ZeroMapKV<'a> for ZeroSlice<T> |
124 | where |
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 | } |
132 | |