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