1use crate::value_vtable;
2use crate::*;
3use core::num::NonZero;
4use typeid::ConstTypeId;
5
6unsafe impl Facet<'_> for ConstTypeId {
7 const SHAPE: &'static Shape = &const {
8 Shape::builder_for_sized::<Self>()
9 .vtable(value_vtable!(ConstTypeId, |f, _opts| write!(
10 f,
11 "{}",
12 Self::SHAPE.type_identifier
13 )))
14 .type_identifier("ConstTypeId")
15 .def(Def::Scalar)
16 .ty(Type::User(UserType::Opaque))
17 .build()
18 };
19}
20
21unsafe impl Facet<'_> for core::any::TypeId {
22 const SHAPE: &'static Shape = &const {
23 Shape::builder_for_sized::<Self>()
24 .vtable(value_vtable!(core::any::TypeId, |f, _opts| write!(
25 f,
26 "{}",
27 Self::SHAPE.type_identifier
28 )))
29 .type_identifier("TypeId")
30 .def(Def::Scalar)
31 .ty(Type::User(UserType::Opaque))
32 .build()
33 };
34}
35
36unsafe impl Facet<'_> for () {
37 const SHAPE: &'static Shape = &const {
38 Shape::builder_for_sized::<Self>()
39 .vtable(value_vtable!((), |f, _opts| write!(f, "()")))
40 .type_identifier("()")
41 .ty(Type::User(UserType::Struct(StructType {
42 repr: Repr::default(),
43 kind: StructKind::Tuple,
44 fields: &[],
45 })))
46 .build()
47 };
48}
49
50unsafe impl<'a, T: ?Sized + 'a> Facet<'a> for core::marker::PhantomData<T> {
51 const SHAPE: &'static Shape = &const {
52 Shape::builder_for_sized::<Self>()
53 .vtable(value_vtable!((), |f, _opts| write!(
55 f,
56 "{}",
57 Self::SHAPE.type_identifier
58 )))
59 .type_identifier("PhantomData")
60 .def(Def::Scalar)
61 .ty(Type::User(UserType::Struct(StructType {
62 repr: Repr::default(),
63 kind: StructKind::Unit,
64 fields: &[],
65 })))
66 .build()
67 };
68}
69
70unsafe impl Facet<'_> for char {
71 const SHAPE: &'static Shape = &const {
72 Shape::builder_for_sized::<Self>()
73 .vtable(value_vtable!(char, |f, _opts| write!(
74 f,
75 "{}",
76 Self::SHAPE.type_identifier
77 )))
78 .type_identifier("char")
79 .def(Def::Scalar)
80 .ty(Type::Primitive(PrimitiveType::Textual(TextualType::Char)))
81 .build()
82 };
83}
84
85unsafe impl Facet<'_> for str {
86 const SHAPE: &'static Shape = &const {
87 Shape::builder_for_unsized::<Self>()
88 .vtable(value_vtable!(str, |f, _opts| write!(
89 f,
90 "{}",
91 Self::SHAPE.type_identifier
92 )))
93 .type_identifier("str")
94 .ty(Type::Primitive(PrimitiveType::Textual(TextualType::Str)))
95 .def(Def::Scalar)
96 .build()
97 };
98}
99
100unsafe impl Facet<'_> for bool {
101 const SHAPE: &'static Shape = &const {
102 Shape::builder_for_sized::<Self>()
103 .vtable(value_vtable!(bool, |f, _opts| write!(
104 f,
105 "{}",
106 Self::SHAPE.type_identifier
107 )))
108 .type_identifier("bool")
109 .def(Def::Scalar)
110 .ty(Type::Primitive(PrimitiveType::Boolean))
111 .build()
112 };
113}
114
115macro_rules! impl_facet_for_integer {
116 ($type:ty) => {
117 unsafe impl<'a> Facet<'a> for $type {
118 const SHAPE: &'static Shape = &const {
119 Shape::builder_for_sized::<Self>()
120 .vtable(value_vtable!($type, |f, _opts| write!(
121 f,
122 "{}",
123 Self::SHAPE.type_identifier
124 )))
125 .type_identifier(stringify!($type))
126 .ty(Type::Primitive(PrimitiveType::Numeric(
127 NumericType::Integer {
128 signed: (1 as $type).checked_neg().is_some(),
129 },
130 )))
131 .def(Def::Scalar)
132 .build()
133 };
134 }
135
136 unsafe impl<'a> Facet<'a> for NonZero<$type> {
137 const SHAPE: &'static Shape = &const {
138 Shape::builder_for_sized::<Self>()
139 .vtable({
140 unsafe fn try_from<'dst>(
142 src_ptr: PtrConst<'_>,
143 src_shape: &'static Shape,
144 dst: PtrUninit<'dst>,
145 ) -> Result<PtrMut<'dst>, TryFromError> {
146 if src_shape == <$type as Facet>::SHAPE {
147 let value = unsafe { *src_ptr.get::<$type>() };
149 let nz = NonZero::new(value).ok_or_else(|| {
150 TryFromError::Generic("value should be non-zero")
151 })?;
152
153 Ok(unsafe { dst.put(nz) })
155 } else {
156 let inner_try_from = <$type as Facet>::SHAPE
157 .vtable
158 .try_from
159 .ok_or(TryFromError::UnsupportedSourceShape {
160 src_shape,
161 expected: &[<$type as Facet>::SHAPE],
162 })?;
163
164 let inner_result =
168 unsafe { (inner_try_from)(src_ptr, src_shape, dst) };
169 match inner_result {
170 Ok(result) => {
171 let value = unsafe { *result.get::<$type>() };
173 let nz = NonZero::new(value).ok_or_else(|| {
174 TryFromError::Generic("value should be non-zero")
175 })?;
176 Ok(unsafe { dst.put(nz) })
177 }
178 Err(e) => Err(e),
179 }
180 }
181 }
182
183 unsafe fn try_into_inner<'dst>(
184 src_ptr: PtrMut<'_>,
185 dst: PtrUninit<'dst>,
186 ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
187 let nz = unsafe { *src_ptr.get::<NonZero<$type>>() };
189 Ok(unsafe { dst.put(nz.get()) })
191 }
192
193 unsafe fn try_borrow_inner(
194 src_ptr: PtrConst<'_>,
195 ) -> Result<PtrConst<'_>, TryBorrowInnerError> {
196 Ok(src_ptr)
198 }
199
200 let mut vtable = value_vtable!($type, |f, _opts| write!(
201 f,
202 "{}<{}>",
203 Self::SHAPE.type_identifier,
204 stringify!($type)
205 ));
206
207 {
209 vtable.try_from = Some(try_from);
210 vtable.try_into_inner = Some(try_into_inner);
211 vtable.try_borrow_inner = Some(try_borrow_inner);
212 }
213
214 vtable
215 })
216 .type_identifier("NonZero")
217 .def(Def::Scalar)
218 .ty(Type::User(UserType::Struct(StructType {
219 repr: Repr::transparent(),
220 kind: StructKind::TupleStruct,
221 fields: &const {
222 [Field::builder()
223 .name("0")
224 .shape(|| <$type>::SHAPE)
227 .offset(0)
228 .flags(FieldFlags::EMPTY)
229 .build()]
230 },
231 })))
232 .inner(<$type as Facet>::SHAPE)
233 .build()
234 };
235 }
236 };
237}
238
239impl_facet_for_integer!(u8);
240impl_facet_for_integer!(i8);
241impl_facet_for_integer!(u16);
242impl_facet_for_integer!(i16);
243impl_facet_for_integer!(u32);
244impl_facet_for_integer!(i32);
245impl_facet_for_integer!(u64);
246impl_facet_for_integer!(i64);
247impl_facet_for_integer!(u128);
248impl_facet_for_integer!(i128);
249impl_facet_for_integer!(usize);
250impl_facet_for_integer!(isize);
251
252unsafe impl Facet<'_> for f32 {
253 const SHAPE: &'static Shape = &const {
254 Shape::builder_for_sized::<Self>()
255 .vtable(value_vtable!(f32, |f, _opts| write!(
256 f,
257 "{}",
258 Self::SHAPE.type_identifier
259 )))
260 .type_identifier("f32")
261 .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
262 .def(Def::Scalar)
263 .build()
264 };
265}
266
267unsafe impl Facet<'_> for f64 {
268 const SHAPE: &'static Shape = &const {
269 Shape::builder_for_sized::<Self>()
270 .vtable({
271 let mut vtable =
272 value_vtable!(f64, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier));
273
274 {
275 vtable.try_from = Some(|source, source_shape, dest| {
276 if source_shape == Self::SHAPE {
277 return Ok(unsafe { dest.copy_from(source, source_shape)? });
278 }
279 if source_shape == u64::SHAPE {
280 let value: u64 = *unsafe { source.get::<u64>() };
281 let converted: f64 = value as f64;
282 return Ok(unsafe { dest.put::<f64>(converted) });
283 }
284 if source_shape == i64::SHAPE {
285 let value: i64 = *unsafe { source.get::<i64>() };
286 let converted: f64 = value as f64;
287 return Ok(unsafe { dest.put::<f64>(converted) });
288 }
289 if source_shape == f32::SHAPE {
290 let value: f32 = *unsafe { source.get::<f32>() };
291 let converted: f64 = value as f64;
292 return Ok(unsafe { dest.put::<f64>(converted) });
293 }
294 Err(TryFromError::UnsupportedSourceShape {
295 src_shape: source_shape,
296 expected: &[Self::SHAPE, u64::SHAPE, i64::SHAPE, f32::SHAPE],
297 })
298 });
299 }
300
301 vtable
302 })
303 .type_identifier("f64")
304 .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
305 .def(Def::Scalar)
306 .build()
307 };
308}
309
310unsafe impl Facet<'_> for core::net::SocketAddr {
311 const SHAPE: &'static Shape = &const {
312 Shape::builder_for_sized::<Self>()
313 .vtable(value_vtable!(core::net::SocketAddr, |f, _opts| write!(
314 f,
315 "{}",
316 Self::SHAPE.type_identifier
317 )))
318 .type_identifier("SocketAddr")
319 .ty(Type::User(UserType::Opaque))
320 .def(Def::Scalar)
321 .build()
322 };
323}
324
325unsafe impl Facet<'_> for core::net::IpAddr {
326 const SHAPE: &'static Shape = &const {
327 Shape::builder_for_sized::<Self>()
328 .vtable(value_vtable!(core::net::IpAddr, |f, _opts| write!(
329 f,
330 "{}",
331 Self::SHAPE.type_identifier
332 )))
333 .type_identifier("IpAddr")
334 .ty(Type::User(UserType::Opaque))
335 .def(Def::Scalar)
336 .build()
337 };
338}
339
340unsafe impl Facet<'_> for core::net::Ipv4Addr {
341 const SHAPE: &'static Shape = &const {
342 Shape::builder_for_sized::<Self>()
343 .vtable(value_vtable!(core::net::Ipv4Addr, |f, _opts| write!(
344 f,
345 "{}",
346 Self::SHAPE.type_identifier
347 )))
348 .type_identifier("Ipv4Addr")
349 .ty(Type::User(UserType::Opaque))
350 .def(Def::Scalar)
351 .build()
352 };
353}
354
355unsafe impl Facet<'_> for core::net::Ipv6Addr {
356 const SHAPE: &'static Shape = &const {
357 Shape::builder_for_sized::<Self>()
358 .vtable(value_vtable!(core::net::Ipv6Addr, |f, _opts| write!(
359 f,
360 "{}",
361 Self::SHAPE.type_identifier
362 )))
363 .type_identifier("Ipv6Addr")
364 .ty(Type::User(UserType::Opaque))
365 .def(Def::Scalar)
366 .build()
367 };
368}