1use 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)]
9pub const fn shape_of_opaque<TStruct, TField>(_f: &dyn Fn(&TStruct) -> &TField) -> &'static Shape
10where
11 Opaque<TField>: Facet,
12{
13 Opaque::<TField>::SHAPE
14}
15
16pub struct Opaque<T>(T);
18
19#[macro_export]
43macro_rules! value_vtable {
44 ($type_name:ty, $type_name_fn:expr) => {
45 &$crate::value_vtable_inner!($type_name, $type_name_fn)
46 };
47}
48
49#[macro_export]
51macro_rules! value_vtable_inner {
52 ($type_name:ty, $type_name_fn:expr) => {
53 const {
54 let mut builder = $crate::ValueVTable::builder()
55 .type_name($type_name_fn)
56 .drop_in_place(|data| unsafe { data.drop_in_place::<$type_name>() });
57
58 if $crate::spez::impls!($type_name: core::fmt::Display) {
59 builder = builder.display(|data, f| {
60 use $crate::spez::*;
61 (&&Spez(unsafe { data.get::<$type_name>() })).spez_display(f)
62 });
63 }
64
65 if $crate::spez::impls!($type_name: core::fmt::Debug) {
66 builder = builder.debug(|data, f| {
67 use $crate::spez::*;
68 (&&Spez(unsafe { data.get::<$type_name>() })).spez_debug(f)
69 });
70 }
71
72 if $crate::spez::impls!($type_name: core::default::Default) {
73 builder = builder.default_in_place(|target| {
74 use $crate::spez::*;
75 unsafe { (&&SpezEmpty::<$type_name>::SPEZ).spez_default_in_place(target) }
76 });
77 }
78
79 if $crate::spez::impls!($type_name: core::clone::Clone) {
80 builder = builder.clone_into(|src, dst| {
81 use $crate::spez::*;
82 unsafe { (&&Spez(src.get::<$type_name>())).spez_clone_into(dst) }
83 });
84 }
85
86 {
87 let mut traits = $crate::MarkerTraits::empty();
88 if $crate::spez::impls!($type_name: core::cmp::Eq) {
89 traits = traits.union($crate::MarkerTraits::EQ);
90 }
91 if $crate::spez::impls!($type_name: core::marker::Send) {
92 traits = traits.union($crate::MarkerTraits::SEND);
93 }
94 if $crate::spez::impls!($type_name: core::marker::Sync) {
95 traits = traits.union($crate::MarkerTraits::SYNC);
96 }
97 if $crate::spez::impls!($type_name: core::marker::Copy) {
98 traits = traits.union($crate::MarkerTraits::COPY);
99 }
100 if $crate::spez::impls!($type_name: core::marker::Unpin) {
101 traits = traits.union($crate::MarkerTraits::UNPIN);
102 }
103 builder = builder.marker_traits(traits);
104 }
105
106 if $crate::spez::impls!($type_name: core::cmp::PartialEq) {
107 builder = builder.eq(|left, right| {
108 use $crate::spez::*;
109 (&&Spez(unsafe { left.get::<$type_name>() }))
110 .spez_eq(&&Spez(unsafe { right.get::<$type_name>() }))
111 });
112 }
113
114 if $crate::spez::impls!($type_name: core::cmp::PartialOrd) {
115 builder = builder.partial_ord(|left, right| {
116 use $crate::spez::*;
117 (&&Spez(unsafe { left.get::<$type_name>() }))
118 .spez_partial_cmp(&&Spez(unsafe { right.get::<$type_name>() }))
119 });
120 }
121
122 if $crate::spez::impls!($type_name: core::cmp::Ord) {
123 builder = builder.ord(|left, right| {
124 use $crate::spez::*;
125 (&&Spez(unsafe { left.get::<$type_name>() }))
126 .spez_cmp(&&Spez(unsafe { right.get::<$type_name>() }))
127 });
128 }
129
130 if $crate::spez::impls!($type_name: core::hash::Hash) {
131 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
132 use $crate::spez::*;
133 use $crate::HasherProxy;
134 (&&Spez(unsafe { value.get::<$type_name>() }))
135 .spez_hash(&mut unsafe { HasherProxy::new(hasher_this, hasher_write_fn) })
136 });
137 }
138
139 if $crate::spez::impls!($type_name: core::str::FromStr) {
140 builder = builder.parse(|s, target| {
141 use $crate::spez::*;
142 let res = unsafe { (&&SpezEmpty::<$type_name>::SPEZ).spez_parse(s, target) };
143 res.map(|_| unsafe { target.assume_init() })
144 });
145 }
146
147 builder.build()
148 }
149 };
150}