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