merde_core/
with_lifetime.rs

1use std::{
2    borrow::Cow,
3    collections::{HashMap, HashSet, VecDeque},
4    sync::Arc,
5};
6
7use crate::{CowStr, Value};
8
9/// Allow instantiating a type with a lifetime parameter, which in
10/// turn lets us require `Deserialize<'s>` for `CowStr<'s>` for
11/// example, even when `CowStr<'s>` is erased behind a `T`.
12///
13/// See <https://github.com/bearcove/merde/pull/60> for details
14pub trait WithLifetime<'s> {
15    type Lifetimed: 's;
16}
17
18macro_rules! impl_with_lifetime {
19    ($($struct_name:ident $(<$lifetime:lifetime>)?),* $(,)?) => {
20        $(
21            impl_with_lifetime!(@inner $struct_name $(<$lifetime>)?);
22        )*
23    };
24
25    (@inner $struct_name:ident <$lifetime:lifetime>) => {
26        impl<$lifetime, 'instantiated_lifetime> WithLifetime<'instantiated_lifetime>
27            for $struct_name<$lifetime>
28        {
29            type Lifetimed = $struct_name<'instantiated_lifetime>;
30        }
31    };
32
33    (@inner $struct_name:ident) => {
34        impl<'s> WithLifetime<'s> for $struct_name {
35            type Lifetimed = $struct_name;
36        }
37    };
38}
39
40impl<'s, B: ToOwned + ?Sized + 's> WithLifetime<'s> for Cow<'_, B> {
41    type Lifetimed = Cow<'s, B>;
42}
43
44impl<'s> WithLifetime<'s> for &str {
45    type Lifetimed = &'s str;
46}
47
48impl_with_lifetime!(
49    Value<'s>,
50    CowStr<'s>,
51    String,
52    u128,
53    u64,
54    u32,
55    u16,
56    u8,
57    i128,
58    i64,
59    i32,
60    i16,
61    i8,
62    bool,
63    char,
64    usize,
65    isize,
66    f32,
67    f64,
68);
69
70impl WithLifetime<'_> for () {
71    type Lifetimed = ();
72}
73
74impl<'s, T> WithLifetime<'s> for Option<T>
75where
76    T: WithLifetime<'s>,
77{
78    type Lifetimed = Option<T::Lifetimed>;
79}
80
81impl<'s, T> WithLifetime<'s> for Vec<T>
82where
83    T: WithLifetime<'s>,
84{
85    type Lifetimed = Vec<T::Lifetimed>;
86}
87
88impl<'s, T> WithLifetime<'s> for Arc<T>
89where
90    T: WithLifetime<'s>,
91{
92    type Lifetimed = Arc<T::Lifetimed>;
93}
94
95impl<'s, T> WithLifetime<'s> for VecDeque<T>
96where
97    T: WithLifetime<'s>,
98{
99    type Lifetimed = VecDeque<T::Lifetimed>;
100}
101
102impl<'s, T> WithLifetime<'s> for HashSet<T>
103where
104    T: WithLifetime<'s>,
105{
106    type Lifetimed = HashSet<T::Lifetimed>;
107}
108
109impl<'s, K, V, S> WithLifetime<'s> for HashMap<K, V, S>
110where
111    S: 's,
112    K: WithLifetime<'s>,
113    V: WithLifetime<'s>,
114{
115    type Lifetimed = HashMap<K::Lifetimed, V::Lifetimed, S>;
116}
117
118impl<'s, T1: WithLifetime<'s>> WithLifetime<'s> for (T1,) {
119    type Lifetimed = (T1::Lifetimed,);
120}
121
122impl<'s, T1: WithLifetime<'s>, T2: WithLifetime<'s>> WithLifetime<'s> for (T1, T2) {
123    type Lifetimed = (T1::Lifetimed, T2::Lifetimed);
124}
125
126impl<'s, T1: WithLifetime<'s>, T2: WithLifetime<'s>, T3: WithLifetime<'s>> WithLifetime<'s>
127    for (T1, T2, T3)
128{
129    type Lifetimed = (T1::Lifetimed, T2::Lifetimed, T3::Lifetimed);
130}
131
132impl<
133        's,
134        T1: WithLifetime<'s>,
135        T2: WithLifetime<'s>,
136        T3: WithLifetime<'s>,
137        T4: WithLifetime<'s>,
138    > WithLifetime<'s> for (T1, T2, T3, T4)
139{
140    type Lifetimed = (T1::Lifetimed, T2::Lifetimed, T3::Lifetimed, T4::Lifetimed);
141}
142
143impl<
144        's,
145        T1: WithLifetime<'s>,
146        T2: WithLifetime<'s>,
147        T3: WithLifetime<'s>,
148        T4: WithLifetime<'s>,
149        T5: WithLifetime<'s>,
150    > WithLifetime<'s> for (T1, T2, T3, T4, T5)
151{
152    type Lifetimed = (
153        T1::Lifetimed,
154        T2::Lifetimed,
155        T3::Lifetimed,
156        T4::Lifetimed,
157        T5::Lifetimed,
158    );
159}
160
161impl<
162        's,
163        T1: WithLifetime<'s>,
164        T2: WithLifetime<'s>,
165        T3: WithLifetime<'s>,
166        T4: WithLifetime<'s>,
167        T5: WithLifetime<'s>,
168        T6: WithLifetime<'s>,
169    > WithLifetime<'s> for (T1, T2, T3, T4, T5, T6)
170{
171    type Lifetimed = (
172        T1::Lifetimed,
173        T2::Lifetimed,
174        T3::Lifetimed,
175        T4::Lifetimed,
176        T5::Lifetimed,
177        T6::Lifetimed,
178    );
179}
180
181impl<
182        's,
183        T1: WithLifetime<'s>,
184        T2: WithLifetime<'s>,
185        T3: WithLifetime<'s>,
186        T4: WithLifetime<'s>,
187        T5: WithLifetime<'s>,
188        T6: WithLifetime<'s>,
189        T7: WithLifetime<'s>,
190    > WithLifetime<'s> for (T1, T2, T3, T4, T5, T6, T7)
191{
192    type Lifetimed = (
193        T1::Lifetimed,
194        T2::Lifetimed,
195        T3::Lifetimed,
196        T4::Lifetimed,
197        T5::Lifetimed,
198        T6::Lifetimed,
199        T7::Lifetimed,
200    );
201}
202
203impl<
204        's,
205        T1: WithLifetime<'s>,
206        T2: WithLifetime<'s>,
207        T3: WithLifetime<'s>,
208        T4: WithLifetime<'s>,
209        T5: WithLifetime<'s>,
210        T6: WithLifetime<'s>,
211        T7: WithLifetime<'s>,
212        T8: WithLifetime<'s>,
213    > WithLifetime<'s> for (T1, T2, T3, T4, T5, T6, T7, T8)
214{
215    type Lifetimed = (
216        T1::Lifetimed,
217        T2::Lifetimed,
218        T3::Lifetimed,
219        T4::Lifetimed,
220        T5::Lifetimed,
221        T6::Lifetimed,
222        T7::Lifetimed,
223        T8::Lifetimed,
224    );
225}