devela/data/table/value/macros/
impl_traits.rs

1// devela::data::table::value::macros::impls
2//
3//! Implements the traits: `DataValue`*, `DataType`*, `DataRaw`*.
4//
5// TOC
6// - impl_data_value!
7// - impl_data_type!
8// - impl_data_raw!
9
10/// Implements the [`DataValue`] trait.
11#[allow(unused_macros)]
12macro_rules! impl_data_value {
13    (
14        v: $Vname:ident, $vbound:ident,
15        t: $Tname:ident, $tbound:ident,
16        all_are_copy: $all_are_copy:stmt,
17
18        copy:
19            $( $C_name:ident, $C_type:ty
20            ),* ;
21        copy@dep:
22            $( $C_name_dep:ident, $C_type_dep:ty,
23               $C_dep1_dep:literal, $C_dep2_dep:literal
24            ),* ;
25        copy@ptr:
26            $( $C_name_ptr:ident, $C_type_ptr:ty,
27               $C_ptr_ptr:meta
28            ),* ;
29        copy@ptrdep:
30            $( $C_name_ptrdep:ident, $C_type_ptrdep:ty,
31               $C_ptr_ptrdep:meta,
32               $C_dep1_ptrdep:literal, $C_dep2_ptrdep:literal
33            ),* ;
34
35        noncopy:
36            $( $N_name:ident, $N_type:ty
37            ),* ;
38        noncopy@dep:
39            $( $N_name_dep:ident, $N_type_dep:ty,
40               $N_dep1_dep:literal, $N_dep2_dep:literal
41            ),* ;
42        noncopy@ptr:
43            $( $N_name_ptr:ident, $N_type_ptr:ty,
44               $N_ptr_ptr:meta
45            ),* ;
46        noncopy@ptrdep:
47            $( $N_name_ptrdep:ident, $N_type_ptrdep:ty,
48               $N_ptr_ptrdep:meta,
49               $N_dep1_ptrdep:literal, $N_dep2_ptrdep:literal
50            ),* ;
51    ) => { $crate::paste! {
52        impl<V: $vbound> $crate::DataValue for $Vname<V> {
53            type Type = $Tname<V::Type>;
54
55            fn data_values_are_copy() -> bool { $all_are_copy }
56
57            fn data_value_is_copy(&self) -> bool {
58                match self {
59                    $Vname::None => true,
60                    $Vname::Extra(t) => t.data_value_is_copy(),
61
62                    $( $Vname::$C_name(_) => true, )*
63                    $( $Vname::$N_name(_) => false, )*
64
65                    $( // pointer-size dependant
66                        #[cfg($C_ptr_ptr)]
67                        $Vname::$C_name_ptr(_) => true,
68                    )* $(
69                        #[cfg($N_ptr_ptr)]
70                        $Vname::$N_name_ptr(_) => false,
71                    )*
72
73                    $( // feature-gated dependencies
74                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
75                        $Vname::$C_name_dep(_) => true,
76                    )* $(
77                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
78                        $Vname::$N_name_dep(_) => false,
79                    )*
80
81                    $( // pointer-size & feature-gated dependencies
82                        #[cfg(all($C_ptr_ptrdep,
83                            feature = $C_dep1_ptrdep,
84                            feature = $C_dep2_ptrdep))]
85                        $Vname::$C_name_ptrdep(_) => true,
86                    )* $(
87                        #[cfg(all($N_ptr_ptrdep,
88                                feature = $N_dep1_ptrdep,
89                                feature = $N_dep2_ptrdep))]
90                        $Vname::$N_name_ptrdep(_) => false,
91                    )*
92                }
93            }
94            fn data_type(&self) -> Self::Type {
95                match self {
96                    $Vname::None => Self::Type::None,
97                    $Vname::Extra(t) => Self::Type::Extra(t.data_type()),
98
99                    $( $Vname::$C_name(_) => Self::Type::$C_name, )*
100                    $( $Vname::$N_name(_) => Self::Type::$N_name, )*
101
102                    $( // pointer-size dependant
103                        #[cfg($C_ptr_ptr)]
104                        $Vname::$C_name_ptr(_) => Self::Type::$C_name_ptr,
105                    )* $(
106                        #[cfg($N_ptr_ptr)]
107                        $Vname::$N_name_ptr(_) => Self::Type::$N_name_ptr,
108                    )*
109
110                    $( // feature-gated dependencies
111                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
112                        $Vname::$C_name_dep(_) => Self::Type::$C_name_dep,
113                    )* $(
114                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
115                        $Vname::$N_name_dep(_) => Self::Type::$N_type_dep,
116                    )*
117
118                    $( // pointer-size & feature-gated dependencies
119                        #[cfg(all($C_ptr_ptrdep,
120                            feature = $C_dep1_ptrdep,
121                            feature = $C_dep2_ptrdep))]
122                        $Vname::$C_name_ptrdep(_) => Self::Type::$C_name_ptrdep,
123                    )* $(
124                        #[cfg(all($N_ptr_ptrdep,
125                                feature = $N_dep1_ptrdep,
126                                feature = $N_dep2_ptrdep))]
127                        $Vname::$N_name_ptrdep(_) => Self::Type::$N_name_ptrdep,
128                    )*
129                }
130            }
131        }
132    }};
133}
134#[allow(unused_imports)]
135pub(crate) use impl_data_value;
136
137/// Implements the [`DataType`] trait.
138#[allow(unused_macros)]
139macro_rules! impl_data_type {
140    (
141        v: $Vname:ident, $vbound:ident,
142        t: $Tname:ident, $tbound:ident,
143        all_are_copy: $all_are_copy:stmt,
144
145        copy:
146            $( $C_name:ident, $C_type:ty,
147               [def:$C_def:stmt]
148            )* ;
149        copy@dep:
150            $( $C_name_dep:ident, $C_type_dep:ty,
151               $C_dep1_dep:literal, $C_dep2_dep:literal,
152               [def:$C_def_dep:stmt]
153            )* ;
154        copy@ptr:
155            $( $C_name_ptr:ident, $C_type_ptr:ty,
156               $C_ptr_ptr:meta,
157               [def:$C_def_ptr:stmt]
158            )* ;
159        copy@ptrdep:
160            $( $C_name_ptrdep:ident, $C_type_ptrdep:ty,
161               $C_ptr_ptrdep:meta,
162               $C_dep1_ptrdep:literal, $C_dep2_ptrdep:literal,
163               [def:$C_def_ptrdep:stmt]
164            )* ;
165
166        noncopy:
167            $( $N_name:ident, $N_type:ty,
168               [def:$N_def:stmt]
169            )* ;
170        noncopy@dep:
171            $( $N_name_dep:ident, $N_type_dep:ty,
172               $N_dep1_dep:literal, $N_dep2_dep:literal,
173               [def:$N_def_dep:stmt]
174            )* ;
175        noncopy@ptr:
176            $( $N_name_ptr:ident, $N_type_ptr:ty,
177               $N_ptr_ptr:meta,
178               [def:$N_def_ptr:stmt]
179            )* ;
180        noncopy@ptrdep:
181            $( $N_name_ptrdep:ident, $N_type_ptrdep:ty,
182               $N_ptr_ptrdep:meta,
183               $N_dep1_ptrdep:literal, $N_dep2_ptrdep:literal,
184               [def:$N_def_ptrdep:stmt]
185            )* ;
186    ) => { $crate::paste! {
187        impl<T: $tbound> $crate::DataType for $Tname<T> {
188            type Value = $Vname<T::Value>;
189
190            fn data_values_are_copy() -> bool { $all_are_copy }
191
192            fn data_value_is_copy(&self) -> bool {
193                match self {
194                    $Tname::None => true,
195                    $Tname::Extra(t) => t.data_value_is_copy(),
196
197                    $( $Tname::$C_name => true, )*
198                    $( $Tname::$N_name => false, )*
199
200                    $(  // pointer-size dependant
201                        #[cfg($C_ptr_ptr)]
202                        $Tname::$C_name_ptr => true,
203                    )* $(
204                        #[cfg($N_ptr_ptr)]
205                        $Tname::$N_name_ptr => false,
206                    )*
207
208                    $(  // feature-gated dependencies
209                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
210                        $Tname::$C_name_dep => true,
211                    )* $(
212                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
213                        $Tname::$N_name_dep => false,
214                    )*
215
216                    $(  // pointer-size & feature-gated dependencies
217                        #[cfg(all($C_ptr_ptrdep,
218                                feature = $C_dep1_ptrdep,
219                                feature = $C_dep2_ptrdep))]
220                        $Tname::$C_name_ptrdep => true,
221                    )* $(
222                        #[cfg(all($N_ptr_ptrdep,
223                                feature = $N_dep1_ptrdep,
224                                feature = $N_dep2_ptrdep))]
225                        $Tname::$N_name_ptrdep => false,
226                    )*
227                }
228            }
229
230            fn data_value_default(&self) -> Option<Self::Value> {
231                match self {
232                    $Tname::None => Some(Self::Value::None),
233                    $Tname::Extra(t) => Some(Self::Value::Extra(t.data_value_default()?)),
234
235                    $(
236                        $Tname::$C_name =>
237                            $crate::maybe![default: $C_def, $C_type]
238                                .map(Self::Value::$C_name),
239                    )* $(
240                        $Tname::$N_name =>
241                            $crate::maybe![default: $N_def, $N_type]
242                                .map(Self::Value::$N_name),
243                    )*
244
245                    $(  // pointer-size dependant
246                        #[cfg($C_ptr_ptr)]
247                        $Tname::$C_name_ptr =>
248                            $crate::maybe![default: $C_def_ptr, $C_type_ptr]
249                                .map(Self::Value::$C_name_ptr),
250                    )* $(
251                        #[cfg($N_ptr_ptr)]
252                        $Tname::$N_name_ptr =>
253                           $crate::maybe![default: $N_def_ptr, $N_type_ptr]
254                           .map(Self::Value::$N_name_ptr),
255                    )*
256
257                    $(  // feature-gated dependencies
258                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
259                        $Tname::$C_name_dep =>
260                            $crate::maybe![default: $C_def_dep, $C_type_dep]
261                                .map(Self::Value::$C_name_dep),
262                    )* $(
263                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
264                        $Tname::$N_name_dep =>
265                            $crate::maybe![default: $N_def_dep, $N_type_dep]
266                                .map(Self::Value::$N_name_dep),
267                    )*
268
269                    $(  // pointer-size & feature-gated dependencies
270                        #[cfg(all($C_ptr_ptrdep,
271                                feature = $C_dep1_ptrdep,
272                                feature = $C_dep2_ptrdep))]
273                        $Tname::$C_name_ptrdep =>
274                            $crate::maybe![default: $C_def_ptrdep, $C_type_ptrdep]
275                                .map(Self::Value::$C_name_ptrdep),
276                    )* $(
277                        #[cfg(all($N_ptr_ptrdep,
278                                feature = $N_dep1_ptrdep,
279                                feature = $N_dep2_ptrdep))]
280                        $Tname::$N_name_ptrdep =>
281                            $crate::maybe![default: $N_def_ptrdep, $N_type_ptrdep]
282                                .map(Self::Value::$N_name_ptrdep),
283                    )*
284                }
285            }
286
287            fn data_value_align(&self) -> usize {
288                match self {
289                    $Tname::None => align_of::<()>(),
290                    $Tname::Extra(t) => t.data_value_align(),
291
292                    $( $Tname::$C_name => align_of::<$C_type>(), )*
293                    $( $Tname::$N_name => align_of::<$N_type>(), )*
294
295                    $(  // pointer-size dependant
296                        #[cfg($C_ptr_ptr)]
297                        $Tname::$C_name_ptr => align_of::<$C_type_ptr>(),
298                    )* $(
299                        #[cfg($N_ptr_ptr)]
300                        $Tname::$N_name_ptr => align_of::<$N_type_ptr>(),
301                    )*
302
303                    $(  // feature-gated dependencies
304                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
305                        $Tname::$C_name_dep => align_of::<$C_type_dep>(),
306                    )* $(
307                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
308                        $Tname::$N_name_dep => align_of::<$N_type_dep>(),
309                    )*
310
311                    $(  // pointer-size & feature-gated dependencies
312                        #[cfg(all($C_ptr_ptrdep,
313                                feature = $C_dep1_ptrdep,
314                                feature = $C_dep2_ptrdep))]
315                        $Tname::$C_name_ptrdep => align_of::<$C_type_ptrdep>(),
316                    )* $(
317                        #[cfg(all($N_ptr_ptrdep,
318                                feature = $N_dep1_ptrdep,
319                                feature = $N_dep2_ptrdep))]
320                        $Tname::$N_name_ptrdep => align_of::<$N_type_ptrdep>(),
321                    )*
322                }
323            }
324            fn data_value_size(&self) -> usize {
325                match self {
326                    $Tname::None => size_of::<()>(),
327                    $Tname::Extra(t) => t.data_value_size(),
328
329                    $( $Tname::$C_name => size_of::<$C_type>(), )*
330                    $( $Tname::$N_name => size_of::<$N_type>(), )*
331
332                    $(  // pointer-size dependant
333                        #[cfg($C_ptr_ptr)]
334                        $Tname::$C_name_ptr => size_of::<$C_type_ptr>(),
335                    )* $(
336                        #[cfg($N_ptr_ptr)]
337                        $Tname::$N_name_ptr => size_of::<$N_type_ptr>(),
338                    )*
339
340                    $(  // feature-gated dependencies
341                        #[cfg(all(feature = $C_dep1_dep, feature = $C_dep2_dep))]
342                        $Tname::$C_name_dep => size_of::<$C_type_dep>(),
343                    )* $(
344                        #[cfg(all(feature = $N_dep1_dep, feature = $N_dep2_dep))]
345                        $Tname::$N_name_dep => size_of::<$N_type_dep>(),
346                    )*
347
348                    $(  // pointer-size & feature-gated dependencies
349                        #[cfg(all($C_ptr_ptrdep,
350                                feature = $C_dep1_ptrdep, feature = $C_dep2_ptrdep))]
351                        $Tname::$C_name_ptrdep => size_of::<$C_type_ptrdep>(),
352                    )* $(
353                        #[cfg(all($N_ptr_ptrdep,
354                                feature = $N_dep1_ptrdep, feature = $N_dep2_ptrdep))]
355                        $Tname::$N_name_ptrdep => size_of::<$N_type_ptrdep>(),
356                    )*
357                }
358            }
359        }
360    }};
361}
362#[allow(unused_imports)]
363pub(crate) use impl_data_type;
364
365/// Implements the [`DataRaw`] trait.
366#[cfg(all(not(feature = "safe_data"), feature = "unsafe_layout"))]
367#[allow(unused_macros)]
368macro_rules! impl_data_raw {
369    (
370      r: $Rname:ident,
371    ) => {
372        unsafe impl DataRaw for $Rname {}
373    };
374}
375#[cfg(all(not(feature = "safe_data"), feature = "unsafe_layout"))]
376#[allow(unused_imports)]
377pub(crate) use impl_data_raw;