facet_core/impls_core/
scalar.rs

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<'static> = &const {
16        Shape::builder_for_sized::<Self>()
17            .type_identifier("ConstTypeId")
18            .def(Def::Scalar(
19                ScalarDef::builder()
20                    .affinity(&const { ScalarAffinity::opaque().build() })
21                    .build(),
22            ))
23            .ty(Type::User(UserType::Opaque))
24            .build()
25    };
26}
27
28unsafe impl Facet<'_> for core::any::TypeId {
29    const VTABLE: &'static ValueVTable = &const {
30        value_vtable!(core::any::TypeId, |f, _opts| write!(
31            f,
32            "{}",
33            Self::SHAPE.type_identifier
34        ))
35    };
36
37    const SHAPE: &'static Shape<'static> = &const {
38        Shape::builder_for_sized::<Self>()
39            .type_identifier("TypeId")
40            .def(Def::Scalar(
41                ScalarDef::builder()
42                    .affinity(&const { ScalarAffinity::opaque().build() })
43                    .build(),
44            ))
45            .ty(Type::User(UserType::Opaque))
46            .build()
47    };
48}
49
50unsafe impl Facet<'_> for () {
51    const VTABLE: &'static ValueVTable = &const { value_vtable!((), |f, _opts| write!(f, "()")) };
52
53    const SHAPE: &'static Shape<'static> = &const {
54        Shape::builder_for_sized::<Self>()
55            .type_identifier("()")
56            .ty(Type::User(UserType::Struct(StructType {
57                repr: Repr::default(),
58                kind: StructKind::Tuple,
59                fields: &[],
60            })))
61            .build()
62    };
63}
64
65unsafe impl<'a, T: ?Sized + 'a> Facet<'a> for core::marker::PhantomData<T> {
66    // TODO: we might be able to do something with specialization re: the shape of T?
67    const VTABLE: &'static ValueVTable =
68        &const { value_vtable!((), |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier)) };
69
70    const SHAPE: &'static Shape<'static> = &const {
71        Shape::builder_for_sized::<Self>()
72            .type_identifier("PhantomData")
73            .def(Def::Scalar(
74                ScalarDef::builder()
75                    .affinity(&const { ScalarAffinity::empty().build() })
76                    .build(),
77            ))
78            .ty(Type::User(UserType::Struct(StructType {
79                repr: Repr::default(),
80                kind: StructKind::Unit,
81                fields: &[],
82            })))
83            .build()
84    };
85}
86
87unsafe impl Facet<'_> for char {
88    const VTABLE: &'static ValueVTable = &const {
89        value_vtable!(char, |f, _opts| write!(
90            f,
91            "{}",
92            Self::SHAPE.type_identifier
93        ))
94    };
95
96    const SHAPE: &'static Shape<'static> = &const {
97        Shape::builder_for_sized::<Self>()
98            .type_identifier("char")
99            .def(Def::Scalar(
100                ScalarDef::builder()
101                    .affinity(&const { ScalarAffinity::char().build() })
102                    .build(),
103            ))
104            .ty(Type::Primitive(PrimitiveType::Textual(TextualType::Char)))
105            .build()
106    };
107}
108
109unsafe impl Facet<'_> for str {
110    const VTABLE: &'static ValueVTable = &const {
111        value_vtable_unsized!(str, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier))
112    };
113
114    const SHAPE: &'static Shape<'static> = &const {
115        Shape::builder_for_unsized::<Self>()
116            .type_identifier("str")
117            .ty(Type::Primitive(PrimitiveType::Textual(TextualType::Str)))
118            .def(Def::Scalar(
119                ScalarDef::builder()
120                    .affinity(&const { ScalarAffinity::string().build() })
121                    .build(),
122            ))
123            .build()
124    };
125}
126
127unsafe impl Facet<'_> for bool {
128    const VTABLE: &'static ValueVTable = &const {
129        value_vtable!(bool, |f, _opts| write!(
130            f,
131            "{}",
132            Self::SHAPE.type_identifier
133        ))
134    };
135
136    const SHAPE: &'static Shape<'static> = &const {
137        Shape::builder_for_sized::<Self>()
138            .type_identifier("bool")
139            .def(Def::Scalar(
140                ScalarDef::builder()
141                    .affinity(&const { ScalarAffinity::boolean().build() })
142                    .build(),
143            ))
144            .ty(Type::Primitive(PrimitiveType::Boolean))
145            .build()
146    };
147}
148
149macro_rules! impl_facet_for_integer {
150    ($type:ty, $affinity:expr, $nz_affinity:expr) => {
151        unsafe impl<'a> Facet<'a> for $type {
152            const VTABLE: &'static ValueVTable = &const {
153                value_vtable!($type, |f, _opts| write!(
154                    f,
155                    "{}",
156                    Self::SHAPE.type_identifier
157                ))
158            };
159
160            const SHAPE: &'static Shape<'static> = &const {
161                Shape::builder_for_sized::<Self>()
162                    .type_identifier(stringify!($type))
163                    .ty(Type::Primitive(PrimitiveType::Numeric(
164                        NumericType::Integer {
165                            signed: (1 as $type).checked_neg().is_some(),
166                        },
167                    )))
168                    .def(Def::Scalar(
169                        ScalarDef::builder().affinity($affinity).build(),
170                    ))
171                    .build()
172            };
173        }
174
175        unsafe impl<'a> Facet<'a> for NonZero<$type> {
176            const VTABLE: &'static ValueVTable = &const {
177                // Define conversion functions for transparency
178                unsafe fn try_from<'shape, 'dst>(
179                    src_ptr: PtrConst<'_>,
180                    src_shape: &'shape Shape<'shape>,
181                    dst: PtrUninit<'dst>,
182                ) -> Result<PtrMut<'dst>, TryFromError<'shape>> {
183                    if src_shape == <$type as Facet>::SHAPE {
184                        // Get the inner value and check that it's non-zero
185                        let value = unsafe { *src_ptr.get::<$type>() };
186                        let nz = NonZero::new(value)
187                            .ok_or_else(|| TryFromError::Generic("value should be non-zero"))?;
188
189                        // Put the NonZero value into the destination
190                        Ok(unsafe { dst.put(nz) })
191                    } else {
192                        let inner_try_from = (<$type as Facet>::SHAPE.vtable.try_from)().ok_or(
193                            TryFromError::UnsupportedSourceShape {
194                                src_shape,
195                                expected: &[<$type as Facet>::SHAPE],
196                            },
197                        )?;
198
199                        // fallback to inner's try_from
200                        // This relies on the fact that `dst` is the same size as `NonZero<$type>`
201                        // which should be true because `NonZero` is `repr(transparent)`
202                        let inner_result = unsafe { (inner_try_from)(src_ptr, src_shape, dst) };
203                        match inner_result {
204                            Ok(result) => {
205                                // After conversion to inner type, wrap as NonZero
206                                let value = unsafe { *result.get::<$type>() };
207                                let nz = NonZero::new(value).ok_or_else(|| {
208                                    TryFromError::Generic("value should be non-zero")
209                                })?;
210                                Ok(unsafe { dst.put(nz) })
211                            }
212                            Err(e) => Err(e),
213                        }
214                    }
215                }
216
217                unsafe fn try_into_inner<'dst>(
218                    src_ptr: PtrMut<'_>,
219                    dst: PtrUninit<'dst>,
220                ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
221                    // Get the NonZero value and extract the inner value
222                    let nz = unsafe { *src_ptr.get::<NonZero<$type>>() };
223                    // Put the inner value into the destination
224                    Ok(unsafe { dst.put(nz.get()) })
225                }
226
227                unsafe fn try_borrow_inner(
228                    src_ptr: PtrConst<'_>,
229                ) -> Result<PtrConst<'_>, TryBorrowInnerError> {
230                    // NonZero<T> has the same memory layout as T, so we can return the input pointer directly
231                    Ok(src_ptr)
232                }
233
234                let mut vtable = value_vtable!($type, |f, _opts| write!(
235                    f,
236                    "{}<{}>",
237                    Self::SHAPE.type_identifier,
238                    stringify!($type)
239                ));
240
241                // Add our new transparency functions
242                vtable.try_from = || Some(try_from);
243                vtable.try_into_inner = || Some(try_into_inner);
244                vtable.try_borrow_inner = || Some(try_borrow_inner);
245
246                vtable
247            };
248
249            const SHAPE: &'static Shape<'static> = &const {
250                // Function to return inner type's shape
251                fn inner_shape() -> &'static Shape<'static> {
252                    <$type as Facet>::SHAPE
253                }
254
255                Shape::builder_for_sized::<Self>()
256                    .type_identifier("NonZero")
257                    .def(Def::Scalar(
258                        ScalarDef::builder().affinity($nz_affinity).build(),
259                    ))
260                    .ty(Type::User(UserType::Struct(StructType {
261                        repr: Repr::transparent(),
262                        kind: StructKind::TupleStruct,
263                        fields: &const {
264                            [Field::builder()
265                                .name("0")
266                                // TODO: is it correct to represent $type here, when we, in
267                                // fact, store $type::NonZeroInner.
268                                .shape(<$type>::SHAPE)
269                                .offset(0)
270                                .flags(FieldFlags::EMPTY)
271                                .build()]
272                        },
273                    })))
274                    .inner(inner_shape)
275                    .build()
276            };
277        }
278    };
279}
280
281static MIN_U8: u8 = u8::MIN;
282static MAX_U8: u8 = u8::MAX;
283static MIN_NZ_U8: NonZero<u8> = NonZero::<u8>::MIN;
284static MAX_NZ_U8: NonZero<u8> = NonZero::<u8>::MAX;
285
286static MIN_I8: i8 = i8::MIN;
287static MAX_I8: i8 = i8::MAX;
288static MIN_NZ_I8: NonZero<i8> = NonZero::<i8>::MIN;
289static MAX_NZ_I8: NonZero<i8> = NonZero::<i8>::MAX;
290
291static MIN_U16: u16 = u16::MIN;
292static MAX_U16: u16 = u16::MAX;
293static MIN_NZ_U16: NonZero<u16> = NonZero::<u16>::MIN;
294static MAX_NZ_U16: NonZero<u16> = NonZero::<u16>::MAX;
295
296static MIN_I16: i16 = i16::MIN;
297static MAX_I16: i16 = i16::MAX;
298static MIN_NZ_I16: NonZero<i16> = NonZero::<i16>::MIN;
299static MAX_NZ_I16: NonZero<i16> = NonZero::<i16>::MAX;
300
301static MIN_U32: u32 = u32::MIN;
302static MAX_U32: u32 = u32::MAX;
303static MIN_NZ_U32: NonZero<u32> = NonZero::<u32>::MIN;
304static MAX_NZ_U32: NonZero<u32> = NonZero::<u32>::MAX;
305
306static MIN_I32: i32 = i32::MIN;
307static MAX_I32: i32 = i32::MAX;
308static MIN_NZ_I32: NonZero<i32> = NonZero::<i32>::MIN;
309static MAX_NZ_I32: NonZero<i32> = NonZero::<i32>::MAX;
310
311static MIN_U64: u64 = u64::MIN;
312static MAX_U64: u64 = u64::MAX;
313static MIN_NZ_U64: NonZero<u64> = NonZero::<u64>::MIN;
314static MAX_NZ_U64: NonZero<u64> = NonZero::<u64>::MAX;
315
316static MIN_I64: i64 = i64::MIN;
317static MAX_I64: i64 = i64::MAX;
318static MIN_NZ_I64: NonZero<i64> = NonZero::<i64>::MIN;
319static MAX_NZ_I64: NonZero<i64> = NonZero::<i64>::MAX;
320
321static MIN_U128: u128 = u128::MIN;
322static MAX_U128: u128 = u128::MAX;
323static MIN_NZ_U128: NonZero<u128> = NonZero::<u128>::MIN;
324static MAX_NZ_U128: NonZero<u128> = NonZero::<u128>::MAX;
325
326static MIN_I128: i128 = i128::MIN;
327static MAX_I128: i128 = i128::MAX;
328static MIN_NZ_I128: NonZero<i128> = NonZero::<i128>::MIN;
329static MAX_NZ_I128: NonZero<i128> = NonZero::<i128>::MAX;
330
331static MIN_USIZE: usize = usize::MIN;
332static MAX_USIZE: usize = usize::MAX;
333static MIN_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MIN;
334static MAX_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MAX;
335
336static MIN_ISIZE: isize = isize::MIN;
337static MAX_ISIZE: isize = isize::MAX;
338static MIN_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MIN;
339static MAX_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MAX;
340
341impl_facet_for_integer!(
342    u8,
343    &const {
344        ScalarAffinity::number()
345            .unsigned_integer(8)
346            .min(PtrConst::new(&raw const MIN_U8))
347            .max(PtrConst::new(&raw const MAX_U8))
348            .build()
349    },
350    &const {
351        ScalarAffinity::number()
352            .unsigned_integer(8)
353            .min(PtrConst::new(&raw const MIN_NZ_U8))
354            .max(PtrConst::new(&raw const MAX_NZ_U8))
355            .build()
356    }
357);
358
359impl_facet_for_integer!(
360    i8,
361    &const {
362        ScalarAffinity::number()
363            .signed_integer(8)
364            .min(PtrConst::new(&raw const MIN_I8))
365            .max(PtrConst::new(&raw const MAX_I8))
366            .build()
367    },
368    &const {
369        ScalarAffinity::number()
370            .signed_integer(8)
371            .min(PtrConst::new(&raw const MIN_NZ_I8))
372            .max(PtrConst::new(&raw const MAX_NZ_I8))
373            .build()
374    }
375);
376
377impl_facet_for_integer!(
378    u16,
379    &const {
380        ScalarAffinity::number()
381            .unsigned_integer(16)
382            .min(PtrConst::new(&raw const MIN_U16))
383            .max(PtrConst::new(&raw const MAX_U16))
384            .build()
385    },
386    &const {
387        ScalarAffinity::number()
388            .unsigned_integer(16)
389            .min(PtrConst::new(&raw const MIN_NZ_U16))
390            .max(PtrConst::new(&raw const MAX_NZ_U16))
391            .build()
392    }
393);
394
395impl_facet_for_integer!(
396    i16,
397    &const {
398        ScalarAffinity::number()
399            .signed_integer(16)
400            .min(PtrConst::new(&raw const MIN_I16))
401            .max(PtrConst::new(&raw const MAX_I16))
402            .build()
403    },
404    &const {
405        ScalarAffinity::number()
406            .signed_integer(16)
407            .min(PtrConst::new(&raw const MIN_NZ_I16))
408            .max(PtrConst::new(&raw const MAX_NZ_I16))
409            .build()
410    }
411);
412
413impl_facet_for_integer!(
414    u32,
415    &const {
416        ScalarAffinity::number()
417            .unsigned_integer(32)
418            .min(PtrConst::new(&raw const MIN_U32))
419            .max(PtrConst::new(&raw const MAX_U32))
420            .build()
421    },
422    &const {
423        ScalarAffinity::number()
424            .unsigned_integer(32)
425            .min(PtrConst::new(&raw const MIN_NZ_U32))
426            .max(PtrConst::new(&raw const MAX_NZ_U32))
427            .build()
428    }
429);
430
431impl_facet_for_integer!(
432    i32,
433    &const {
434        ScalarAffinity::number()
435            .signed_integer(32)
436            .min(PtrConst::new(&raw const MIN_I32))
437            .max(PtrConst::new(&raw const MAX_I32))
438            .build()
439    },
440    &const {
441        ScalarAffinity::number()
442            .signed_integer(32)
443            .min(PtrConst::new(&raw const MIN_NZ_I32))
444            .max(PtrConst::new(&raw const MAX_NZ_I32))
445            .build()
446    }
447);
448
449impl_facet_for_integer!(
450    u64,
451    &const {
452        ScalarAffinity::number()
453            .unsigned_integer(64)
454            .min(PtrConst::new(&raw const MIN_U64))
455            .max(PtrConst::new(&raw const MAX_U64))
456            .build()
457    },
458    &const {
459        ScalarAffinity::number()
460            .unsigned_integer(64)
461            .min(PtrConst::new(&raw const MIN_NZ_U64))
462            .max(PtrConst::new(&raw const MAX_NZ_U64))
463            .build()
464    }
465);
466
467impl_facet_for_integer!(
468    i64,
469    &const {
470        ScalarAffinity::number()
471            .signed_integer(64)
472            .min(PtrConst::new(&raw const MIN_I64))
473            .max(PtrConst::new(&raw const MAX_I64))
474            .build()
475    },
476    &const {
477        ScalarAffinity::number()
478            .signed_integer(64)
479            .min(PtrConst::new(&raw const MIN_NZ_I64))
480            .max(PtrConst::new(&raw const MAX_NZ_I64))
481            .build()
482    }
483);
484
485impl_facet_for_integer!(
486    u128,
487    &const {
488        ScalarAffinity::number()
489            .unsigned_integer(128)
490            .min(PtrConst::new(&raw const MIN_U128))
491            .max(PtrConst::new(&raw const MAX_U128))
492            .build()
493    },
494    &const {
495        ScalarAffinity::number()
496            .unsigned_integer(128)
497            .min(PtrConst::new(&raw const MIN_NZ_U128))
498            .max(PtrConst::new(&raw const MAX_NZ_U128))
499            .build()
500    }
501);
502
503impl_facet_for_integer!(
504    i128,
505    &const {
506        ScalarAffinity::number()
507            .signed_integer(128)
508            .min(PtrConst::new(&raw const MIN_I128))
509            .max(PtrConst::new(&raw const MAX_I128))
510            .build()
511    },
512    &const {
513        ScalarAffinity::number()
514            .signed_integer(128)
515            .min(PtrConst::new(&raw const MIN_NZ_I128))
516            .max(PtrConst::new(&raw const MAX_NZ_I128))
517            .build()
518    }
519);
520
521impl_facet_for_integer!(
522    usize,
523    &const {
524        ScalarAffinity::number()
525            .pointer_sized_unsigned_integer()
526            .min(PtrConst::new(&raw const MIN_USIZE))
527            .max(PtrConst::new(&raw const MAX_USIZE))
528            .build()
529    },
530    &const {
531        ScalarAffinity::number()
532            .pointer_sized_unsigned_integer()
533            .min(PtrConst::new(&raw const MIN_NZ_USIZE))
534            .max(PtrConst::new(&raw const MAX_NZ_USIZE))
535            .build()
536    }
537);
538
539impl_facet_for_integer!(
540    isize,
541    &const {
542        ScalarAffinity::number()
543            .pointer_sized_signed_integer()
544            .min(PtrConst::new(&raw const MIN_ISIZE))
545            .max(PtrConst::new(&raw const MAX_ISIZE))
546            .build()
547    },
548    &const {
549        ScalarAffinity::number()
550            .pointer_sized_signed_integer()
551            .min(PtrConst::new(&raw const MIN_NZ_ISIZE))
552            .max(PtrConst::new(&raw const MAX_NZ_ISIZE))
553            .build()
554    }
555);
556// Constants for f32
557static MIN_F32: f32 = f32::MIN;
558static MAX_F32: f32 = f32::MAX;
559static POSITIVE_INFINITY_F32: f32 = f32::INFINITY;
560static NEGATIVE_INFINITY_F32: f32 = f32::NEG_INFINITY;
561static NAN_F32: f32 = f32::NAN;
562static POSITIVE_ZERO_F32: f32 = 0.0f32;
563static NEGATIVE_ZERO_F32: f32 = -0.0f32;
564static EPSILON_F32: f32 = f32::EPSILON;
565
566// Constants for f64
567static MIN_F64: f64 = f64::MIN;
568static MAX_F64: f64 = f64::MAX;
569static POSITIVE_INFINITY_F64: f64 = f64::INFINITY;
570static NEGATIVE_INFINITY_F64: f64 = f64::NEG_INFINITY;
571static NAN_F64: f64 = f64::NAN;
572static POSITIVE_ZERO_F64: f64 = 0.0f64;
573static NEGATIVE_ZERO_F64: f64 = -0.0f64;
574static EPSILON_F64: f64 = f64::EPSILON;
575
576unsafe impl Facet<'_> for f32 {
577    const VTABLE: &'static ValueVTable =
578        &const { value_vtable!(f32, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier)) };
579
580    const SHAPE: &'static Shape<'static> = &const {
581        Shape::builder_for_sized::<Self>()
582            .type_identifier("f32")
583            .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
584            .def(Def::Scalar(
585                ScalarDef::builder()
586                    .affinity(
587                        &const {
588                            ScalarAffinity::number()
589                                .float(1, 8, f32::MANTISSA_DIGITS as usize - 1, false)
590                                .min(PtrConst::new(&raw const MIN_F32))
591                                .max(PtrConst::new(&raw const MAX_F32))
592                                .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F32))
593                                .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F32))
594                                .nan_sample(PtrConst::new(&raw const NAN_F32))
595                                .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F32))
596                                .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F32))
597                                .epsilon(PtrConst::new(&raw const EPSILON_F32))
598                                .build()
599                        },
600                    )
601                    .build(),
602            ))
603            .build()
604    };
605}
606
607unsafe impl Facet<'_> for f64 {
608    const VTABLE: &'static ValueVTable = &const {
609        let mut vtable =
610            value_vtable!(f64, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier));
611
612        vtable.try_from = || {
613            Some(|source, source_shape, dest| {
614                if source_shape == Self::SHAPE {
615                    return Ok(unsafe { dest.copy_from(source, source_shape)? });
616                }
617                if source_shape == u64::SHAPE {
618                    let value: u64 = *unsafe { source.get::<u64>() };
619                    let converted: f64 = value as f64;
620                    return Ok(unsafe { dest.put::<f64>(converted) });
621                }
622                if source_shape == i64::SHAPE {
623                    let value: i64 = *unsafe { source.get::<i64>() };
624                    let converted: f64 = value as f64;
625                    return Ok(unsafe { dest.put::<f64>(converted) });
626                }
627                if source_shape == f32::SHAPE {
628                    let value: f32 = *unsafe { source.get::<f32>() };
629                    let converted: f64 = value as f64;
630                    return Ok(unsafe { dest.put::<f64>(converted) });
631                }
632                Err(TryFromError::UnsupportedSourceShape {
633                    src_shape: source_shape,
634                    expected: &[Self::SHAPE, u64::SHAPE, i64::SHAPE, f32::SHAPE],
635                })
636            })
637        };
638
639        vtable
640    };
641
642    const SHAPE: &'static Shape<'static> = &const {
643        Shape::builder_for_sized::<Self>()
644            .type_identifier("f64")
645            .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
646            .def(Def::Scalar(
647                ScalarDef::builder()
648                    .affinity(
649                        &const {
650                            ScalarAffinity::number()
651                                .float(1, 11, f64::MANTISSA_DIGITS as usize - 1, false)
652                                .min(PtrConst::new(&raw const MIN_F64))
653                                .max(PtrConst::new(&raw const MAX_F64))
654                                .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F64))
655                                .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F64))
656                                .nan_sample(PtrConst::new(&raw const NAN_F64))
657                                .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F64))
658                                .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F64))
659                                .epsilon(PtrConst::new(&raw const EPSILON_F64))
660                                .build()
661                        },
662                    )
663                    .build(),
664            ))
665            .build()
666    };
667}
668
669unsafe impl Facet<'_> for core::net::SocketAddr {
670    const VTABLE: &'static ValueVTable = &const {
671        value_vtable!(core::net::SocketAddr, |f, _opts| write!(
672            f,
673            "{}",
674            Self::SHAPE.type_identifier
675        ))
676    };
677
678    const SHAPE: &'static Shape<'static> = &const {
679        Shape::builder_for_sized::<Self>()
680            .type_identifier("SocketAddr")
681            .ty(Type::User(UserType::Opaque))
682            .def(Def::Scalar(
683                ScalarDef::builder()
684                    .affinity(&const { ScalarAffinity::socket_addr().build() })
685                    .build(),
686            ))
687            .build()
688    };
689}
690
691unsafe impl Facet<'_> for core::net::IpAddr {
692    const VTABLE: &'static ValueVTable = &const {
693        value_vtable!(core::net::IpAddr, |f, _opts| write!(
694            f,
695            "{}",
696            Self::SHAPE.type_identifier
697        ))
698    };
699
700    const SHAPE: &'static Shape<'static> = &const {
701        Shape::builder_for_sized::<Self>()
702            .type_identifier("IpAddr")
703            .ty(Type::User(UserType::Opaque))
704            .def(Def::Scalar(
705                ScalarDef::builder()
706                    .affinity(&const { ScalarAffinity::ip_addr().build() })
707                    .build(),
708            ))
709            .build()
710    };
711}
712
713unsafe impl Facet<'_> for core::net::Ipv4Addr {
714    const VTABLE: &'static ValueVTable = &const {
715        value_vtable!(core::net::Ipv4Addr, |f, _opts| write!(
716            f,
717            "{}",
718            Self::SHAPE.type_identifier
719        ))
720    };
721
722    const SHAPE: &'static Shape<'static> = &const {
723        Shape::builder_for_sized::<Self>()
724            .type_identifier("Ipv4Addr")
725            .ty(Type::User(UserType::Opaque))
726            .def(Def::Scalar(
727                ScalarDef::builder()
728                    .affinity(&const { ScalarAffinity::ip_addr().build() })
729                    .build(),
730            ))
731            .build()
732    };
733}
734
735unsafe impl Facet<'_> for core::net::Ipv6Addr {
736    const VTABLE: &'static ValueVTable = &const {
737        value_vtable!(core::net::Ipv6Addr, |f, _opts| write!(
738            f,
739            "{}",
740            Self::SHAPE.type_identifier
741        ))
742    };
743
744    const SHAPE: &'static Shape<'static> = &const {
745        Shape::builder_for_sized::<Self>()
746            .type_identifier("Ipv6Addr")
747            .ty(Type::User(UserType::Opaque))
748            .def(Def::Scalar(
749                ScalarDef::builder()
750                    .affinity(&const { ScalarAffinity::ip_addr().build() })
751                    .build(),
752            ))
753            .build()
754    };
755}