facet_core/_trait/
macros.rs1use crate::{Facet, Shape};
2
3#[doc(hidden)]
4pub const fn shape_of<TStruct, TField: Facet>(_f: &dyn Fn(TStruct) -> TField) -> &'static Shape {
5 TField::SHAPE
6}
7
8#[doc(hidden)]
9#[macro_export]
10macro_rules! struct_field {
11 ($struct:ty, $field:tt) => {
12 $crate::Field::builder()
13 .name(stringify!($field))
14 .shape($crate::shape_of(&|s: $struct| s.$field))
15 .offset(::core::mem::offset_of!($struct, $field))
16 .flags($crate::FieldFlags::EMPTY)
17 .build()
18 };
19}
20
21#[doc(hidden)]
22#[macro_export]
23macro_rules! struct_fields {
24 ($struct:ty, ($($field:tt),*)) => {{
25 static FIELDS: &[$crate::Field] = &[ $($crate::struct_field!($struct, $field)),* ];
26 FIELDS
27 }};
28}
29
30#[doc(hidden)]
31#[macro_export]
32macro_rules! enum_unit_variant {
33 ($enum:ty, $variant:ident, $discriminant:expr) => {
34 $crate::Variant::builder()
35 .name(stringify!($variant))
36 .discriminant(Some($discriminant))
37 .kind($crate::VariantKind::Unit)
38 .build()
39 };
40}
41
42#[doc(hidden)]
43#[macro_export]
44macro_rules! enum_tuple_variant {
45 ($enum:ty, $variant:ident, [$(($field_type:ty, $offset:expr)),*], $discriminant:expr) => {{
46 static FIELDS: &[$crate::Field] = &[
47 $(
48 $crate::Field::builder()
49 .name(concat!("_", stringify!($field_type)))
50 .shape(<$field_type>::SHAPE)
51 .offset($offset) .flags($crate::FieldFlags::EMPTY)
53 .build()
54 ),*
55 ];
56
57 $crate::Variant::builder()
58 .name(stringify!($variant))
59 .discriminant(Some($discriminant))
60 .kind($crate::VariantKind::Tuple { fields: FIELDS })
61 .build()
62 }};
63}
64
65#[doc(hidden)]
66#[macro_export]
67macro_rules! enum_struct_variant {
68 ($enum:ty, $variant:ident, {$(($field:ident: $field_type:ty, $offset:expr)),*}, $discriminant:expr) => {{
69 static FIELDS: &[$crate::Field] = &[
70 $(
71 $crate::Field::builder()
72 .name(stringify!($field))
73 .shape(<$field_type>::SHAPE)
74 .offset($offset) .flags($crate::FieldFlags::EMPTY)
76 .build()
77 ),*
78 ];
79
80 $crate::Variant::builder()
81 .name(stringify!($variant))
82 .discriminant(Some($discriminant))
83 .kind($crate::VariantKind::Struct { fields: FIELDS })
84 .build()
85 }};
86}
87
88#[doc(hidden)]
89#[macro_export]
90macro_rules! enum_variants {
91 ($enum:ty, [$($variant:expr),*]) => {{
92 static VARIANTS: &[$crate::Variant] = &[ $($variant),* ];
93 VARIANTS
94 }};
95}
96
97#[macro_export]
121macro_rules! value_vtable {
122 ($type_name:ty, $type_name_fn:expr) => {
123 &const {
124 let mut builder = $crate::ValueVTable::builder()
125 .type_name($type_name_fn)
126 .drop_in_place(|data| unsafe { data.drop_in_place::<$type_name>() });
127
128 if $crate::spez::impls!($type_name: core::fmt::Display) {
129 builder = builder.display(|data, f| {
130 use $crate::spez::*;
131 (&&Spez(unsafe { data.as_ref::<$type_name>() })).spez_display(f)
132 });
133 }
134
135 if $crate::spez::impls!($type_name: core::fmt::Debug) {
136 builder = builder.debug(|data, f| {
137 use $crate::spez::*;
138 (&&Spez(unsafe { data.as_ref::<$type_name>() })).spez_debug(f)
139 });
140 }
141
142 if $crate::spez::impls!($type_name: core::default::Default) {
143 builder = builder.default_in_place(|target| {
144 use $crate::spez::*;
145 unsafe { (&&SpezEmpty::<$type_name>::SPEZ).spez_default_in_place(target) }
146 });
147 }
148
149 if $crate::spez::impls!($type_name: core::clone::Clone) {
150 builder = builder.clone_into(|src, dst| {
151 use $crate::spez::*;
152 unsafe { (&&Spez(src.as_ref::<$type_name>())).spez_clone_into(dst) }
153 });
154 }
155
156 {
157 let mut traits = $crate::MarkerTraits::empty();
158 if $crate::spez::impls!($type_name: core::cmp::Eq) {
159 traits = traits.union($crate::MarkerTraits::EQ);
160 }
161 if $crate::spez::impls!($type_name: core::marker::Send) {
162 traits = traits.union($crate::MarkerTraits::SEND);
163 }
164 if $crate::spez::impls!($type_name: core::marker::Sync) {
165 traits = traits.union($crate::MarkerTraits::SYNC);
166 }
167 if $crate::spez::impls!($type_name: core::marker::Copy) {
168 traits = traits.union($crate::MarkerTraits::COPY);
169 }
170 builder = builder.marker_traits(traits);
171 }
172
173 if $crate::spez::impls!($type_name: core::cmp::PartialEq) {
174 builder = builder.eq(|left, right| {
175 use $crate::spez::*;
176 (&&Spez(unsafe { left.as_ref::<$type_name>() }))
177 .spez_eq(&&Spez(unsafe { right.as_ref::<$type_name>() }))
178 });
179 }
180
181 if $crate::spez::impls!($type_name: core::cmp::PartialOrd) {
182 builder = builder.partial_ord(|left, right| {
183 use $crate::spez::*;
184 (&&Spez(unsafe { left.as_ref::<$type_name>() }))
185 .spez_partial_cmp(&&Spez(unsafe { right.as_ref::<$type_name>() }))
186 });
187 }
188
189 if $crate::spez::impls!($type_name: core::cmp::Ord) {
190 builder = builder.ord(|left, right| {
191 use $crate::spez::*;
192 (&&Spez(unsafe { left.as_ref::<$type_name>() }))
193 .spez_cmp(&&Spez(unsafe { right.as_ref::<$type_name>() }))
194 });
195 }
196
197 if $crate::spez::impls!($type_name: core::hash::Hash) {
198 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
199 use $crate::spez::*;
200 use $crate::HasherProxy;
201 (&&Spez(unsafe { value.as_ref::<$type_name>() }))
202 .spez_hash(&mut unsafe { HasherProxy::new(hasher_this, hasher_write_fn) })
203 });
204 }
205
206 if $crate::spez::impls!($type_name: core::str::FromStr) {
207 builder = builder.parse(|s, target| {
208 use $crate::spez::*;
209 let res = unsafe { (&&SpezEmpty::<$type_name>::SPEZ).spez_parse(s, target) };
210 res.map(|_| unsafe { target.assume_init() })
211 });
212 }
213
214 builder.build()
215 }
216 };
217}