devela/data/value/macros/
impl_traits.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
// devela::data::value::macros::impls
//
//!
//
// TOC
// - impl_data_type
// - impl_data_value
// - impl_data_raw/

/// Implements the `DataType` trait.
#[allow(unused_macros)]
macro_rules! impl_data_type {
    (
        v: $cname:ident, $cbound:ident,
        t: $tname:ident, $tbound:ident,
        is_copy: $is_copy:stmt,
        // has_default: $default:stmt, // TODO
        copy_variants:
            $( $cvname:ident, $cvtype:ty ),* ;
        copy_variants_dep:
            $( $cvname_dep:ident, $cvtype_dep:ty,
            $cvdep1_dep:literal, $cvdep2_dep:literal ),* ;
        copy_variants_psize:
            $( $cvname_psize:ident, $cvtype_psize:ty, $cvpsize_psize:meta ),* ;
        copy_variants_psize_dep:
            $( $cvname_psize_dep:ident, $cvtype_psize_dep:ty,
            $cvpsize_psize_dep:meta, $cvdep1_psize_dep:literal, $cvdep2_psize_dep:literal ),* ;
        noncopy_variants:
            $( $vname:ident, $vtype:ty ),* ;
        noncopy_variants_dep:
            $( $vname_dep:ident, $vtype_dep:ty,
            $vdep1_dep:literal, $vdep2_dep:literal ),* ;
        noncopy_variants_psize_dep:
            $( $vname_psize_dep:ident, $vtype_psize_dep:ty,
            $vpsize_psize_dep:meta, $vdep1_psize_dep:literal, $vdep2_psize_dep:literal ),* ;
    ) => { $crate::paste! {
        impl<T: $tbound> $crate::DataType for $tname<T> {
            type Value = $cname<T::Value>;

            fn data_value_is_copy(&self) -> bool { $is_copy }

            fn data_value_default(&self) -> Option<Self::Value> {
                match self {
                    $tname::NoData => Some(Self::Value::NoData),
                    $tname::Extra(t) => Some(Self::Value::Extra(t.data_value_default()?)),

                    // TODO: have to pass it as an argument for each type
                    // $( $tname::$cvname =>
                    //     if $def { Some(Self::Type::$cvname($cvtype::default())) } else { None },
                    // )*
                    // $( $tname::$vname => Some(Self::Type::$vtype), )*

                    _ => todo![], // TEMP

                    // $( // pointer-size dependant
                    //     #[cfg($cvpsize_psize)]
                    //     $tname::$cvname_psize => Self::Type::$cvtype_psize,
                    // )*
                    //
                    // $( // feature-gated dependencies
                    //     #[cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))]
                    //     #[cfg_attr(feature = "nightly_doc",
                    //         doc(cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))))]
                    //     $tname::$cvname_dep => Self::Type::$cvtype_dep,
                    // )*
                    // $(
                    //     #[cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))]
                    //     #[cfg_attr(feature = "nightly_doc",
                    //         doc(cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))))]
                    //     $tname::$vname_dep => Self::Type::$vtype_dep,
                    // )*
                    //
                    // $( // pointer-size & feature-gated dependencies
                    //     #[cfg(all($cvpsize_psize_dep,
                    //             feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))]
                    //     #[cfg_attr(feature = "nightly_doc",
                    //         doc(cfg(all(feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))))]
                    //     $tname::$cvname_psize_dep => Self::Type::$cvtype_psize_dep,
                    // )*
                    // $(
                    //     #[cfg(all($vpsize_psize_dep,
                    //             feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))]
                    //     #[cfg_attr(feature = "nightly_doc",
                    //         doc(cfg(all(feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))))]
                    //     $tname::$vname_psize_dep => Self::Type::$vtype_psize_dep,
                    // )*
                }
            }

            fn data_value_align(&self) -> usize {
                match self {
                    $tname::NoData => align_of::<()>(),
                    $tname::Extra(t) => t.data_value_align(),

                    $( $tname::$cvname => align_of::<$cvtype>(), )*
                    $( $tname::$vname => align_of::<$vtype>(), )*

                    $( // pointer-size dependant
                        #[cfg($cvpsize_psize)]
                        $tname::$cvname_psize => align_of::<$cvtype_psize>(),
                    )*

                    $( // feature-gated dependencies
                        #[cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))))]
                        $tname::$cvname_dep => align_of::<$cvtype_dep>(),
                    )*
                    $(
                        #[cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))))]
                        $tname::$vname_dep => align_of::<$vtype_dep>(),
                    )*

                    $( // pointer-size & feature-gated dependencies
                        #[cfg(all($cvpsize_psize_dep,
                                feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))))]
                        $tname::$cvname_psize_dep => align_of::<$cvtype_psize_dep>(),
                    )*
                    $(
                        #[cfg(all($vpsize_psize_dep,
                                feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))))]
                        $tname::$vname_psize_dep => align_of::<$vtype_psize_dep>(),
                    )*
                }
            }
            fn data_value_size(&self) -> usize {
                match self {
                    $tname::NoData => size_of::<()>(),
                    $tname::Extra(t) => t.data_value_size(),

                    $( $tname::$cvname => size_of::<$cvtype>(), )*
                    $( $tname::$vname => size_of::<$vtype>(), )*

                    $( // pointer-size dependant
                        #[cfg($cvpsize_psize)]
                        $tname::$cvname_psize => size_of::<$cvtype_psize>(),
                    )*

                    $( // feature-gated dependencies
                        #[cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))))]
                        $tname::$cvname_dep => size_of::<$cvtype_dep>(),
                    )*
                    $(
                        #[cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))))]
                        $tname::$vname_dep => size_of::<$vtype_dep>(),
                    )*

                    $( // pointer-size & feature-gated dependencies
                        #[cfg(all($cvpsize_psize_dep,
                                feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))))]
                        $tname::$cvname_psize_dep => size_of::<$cvtype_psize_dep>(),
                    )*
                    $(
                        #[cfg(all($vpsize_psize_dep,
                                feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))))]
                        $tname::$vname_psize_dep => size_of::<$vtype_psize_dep>(),
                    )*
                }
            }
        }
    }};
}
#[allow(unused_imports)]
pub(crate) use impl_data_type;

/// Implements the [`DataValue`] trait.
#[allow(unused_macros)]
macro_rules! impl_data_value {
    (
        v: $cname:ident, $cbound:ident,
        t: $tname:ident, $tbound:ident,
        is_copy: $is_copy:stmt,
        copy_variants:
            $( $cvname:ident, $cvtype:ty ),* ;
        copy_variants_dep:
            $( $cvname_dep:ident, $cvtype_dep:ty,
            $cvdep1_dep:literal, $cvdep2_dep:literal ),* ;
        copy_variants_psize:
            $( $cvname_psize:ident, $cvtype_psize:ty, $cvpsize_psize:meta ),* ;
        copy_variants_psize_dep:
            $( $cvname_psize_dep:ident, $cvtype_psize_dep:ty,
            $cvpsize_psize_dep:meta, $cvdep1_psize_dep:literal, $cvdep2_psize_dep:literal ),* ;
        noncopy_variants:
            $( $vname:ident, $vtype:ty ),* ;
        noncopy_variants_dep:
            $( $vname_dep:ident, $vtype_dep:ty,
            $vdep1_dep:literal, $vdep2_dep:literal ),* ;
        noncopy_variants_psize_dep:
            $( $vname_psize_dep:ident, $vtype_psize_dep:ty,
            $vpsize_psize_dep:meta, $vdep1_psize_dep:literal, $vdep2_psize_dep:literal ),* ;
    ) => { $crate::paste! {
        impl<V: $cbound> $crate::DataValue for $cname<V> {
            type Type = $tname<V::Type>;

            fn data_value_is_copy(&self) -> bool { $is_copy }
            fn data_type(&self) -> Self::Type {
                match self {
                    $cname::NoData => Self::Type::NoData,
                    $cname::Extra(t) => Self::Type::Extra(t.data_type()),

                    $( $cname::$cvname(_) => Self::Type::$cvname, )*
                    $( $cname::$vname(_) => Self::Type::$vname, )*

                    $( // pointer-size dependant
                        #[cfg($cvpsize_psize)]
                        $cname::$cvname_psize(_) => Self::Type::$cvname_psize,
                    )*

                    $( // feature-gated dependencies
                        #[cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_dep, feature = $cvdep2_dep))))]
                        $cname::$cvname_dep(_) => Self::Type::$cvname_dep,
                    )*
                    $(
                        #[cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_dep, feature = $vdep2_dep))))]
                        $cname::$vname_dep(_) => Self::Type::$vtype_dep,
                    )*

                    $( // pointer-size & feature-gated dependencies
                        #[cfg(all($cvpsize_psize_dep,
                            feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $cvdep1_psize_dep, feature = $cvdep2_psize_dep))))]
                        $cname::$cvname_psize_dep(_) => Self::Type::$cvname_psize_dep,
                    )*
                    $(
                        #[cfg(all($vpsize_psize_dep,
                                feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))]
                        #[cfg_attr(feature = "nightly_doc",
                            doc(cfg(all(feature = $vdep1_psize_dep, feature = $vdep2_psize_dep))))]
                        $cname::$vname_psize_dep(_) => Self::Type::$vname_psize_dep,
                    )*
                }
            }
        }
    }};
}
#[allow(unused_imports)]
pub(crate) use impl_data_value;

/// Implements the `DataRaw` trait.
#[cfg(all(not(feature = "safe_data"), feature = "unsafe_layout"))]
#[allow(unused_macros)]
macro_rules! impl_data_raw {
    (
      b: $bname:ident,
    ) => {
        unsafe impl DataRaw for $bname {}
    };
}
#[cfg(all(not(feature = "safe_data"), feature = "unsafe_layout"))]
#[allow(unused_imports)]
pub(crate) use impl_data_raw;