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 =
193                            (<$type as Facet>::SHAPE.vtable.sized().unwrap().try_from)().ok_or(
194                                TryFromError::UnsupportedSourceShape {
195                                    src_shape,
196                                    expected: &[<$type as Facet>::SHAPE],
197                                },
198                            )?;
199
200                        // fallback to inner's try_from
201                        // This relies on the fact that `dst` is the same size as `NonZero<$type>`
202                        // which should be true because `NonZero` is `repr(transparent)`
203                        let inner_result = unsafe { (inner_try_from)(src_ptr, src_shape, dst) };
204                        match inner_result {
205                            Ok(result) => {
206                                // After conversion to inner type, wrap as NonZero
207                                let value = unsafe { *result.get::<$type>() };
208                                let nz = NonZero::new(value).ok_or_else(|| {
209                                    TryFromError::Generic("value should be non-zero")
210                                })?;
211                                Ok(unsafe { dst.put(nz) })
212                            }
213                            Err(e) => Err(e),
214                        }
215                    }
216                }
217
218                unsafe fn try_into_inner<'dst>(
219                    src_ptr: PtrMut<'_>,
220                    dst: PtrUninit<'dst>,
221                ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
222                    // Get the NonZero value and extract the inner value
223                    let nz = unsafe { *src_ptr.get::<NonZero<$type>>() };
224                    // Put the inner value into the destination
225                    Ok(unsafe { dst.put(nz.get()) })
226                }
227
228                unsafe fn try_borrow_inner(
229                    src_ptr: PtrConst<'_>,
230                ) -> Result<PtrConst<'_>, TryBorrowInnerError> {
231                    // NonZero<T> has the same memory layout as T, so we can return the input pointer directly
232                    Ok(src_ptr)
233                }
234
235                let mut vtable = value_vtable!($type, |f, _opts| write!(
236                    f,
237                    "{}<{}>",
238                    Self::SHAPE.type_identifier,
239                    stringify!($type)
240                ));
241
242                // Add our new transparency functions
243                {
244                    let vtable_sized = vtable.sized_mut().unwrap();
245                    vtable_sized.try_from = || Some(try_from);
246                    vtable_sized.try_into_inner = || Some(try_into_inner);
247                    vtable_sized.try_borrow_inner = || Some(try_borrow_inner);
248                }
249
250                vtable
251            };
252
253            const SHAPE: &'static Shape<'static> = &const {
254                // Function to return inner type's shape
255                fn inner_shape() -> &'static Shape<'static> {
256                    <$type as Facet>::SHAPE
257                }
258
259                Shape::builder_for_sized::<Self>()
260                    .type_identifier("NonZero")
261                    .def(Def::Scalar(
262                        ScalarDef::builder().affinity($nz_affinity).build(),
263                    ))
264                    .ty(Type::User(UserType::Struct(StructType {
265                        repr: Repr::transparent(),
266                        kind: StructKind::TupleStruct,
267                        fields: &const {
268                            [Field::builder()
269                                .name("0")
270                                // TODO: is it correct to represent $type here, when we, in
271                                // fact, store $type::NonZeroInner.
272                                .shape(<$type>::SHAPE)
273                                .offset(0)
274                                .flags(FieldFlags::EMPTY)
275                                .build()]
276                        },
277                    })))
278                    .inner(inner_shape)
279                    .build()
280            };
281        }
282    };
283}
284
285static MIN_U8: u8 = u8::MIN;
286static MAX_U8: u8 = u8::MAX;
287static MIN_NZ_U8: NonZero<u8> = NonZero::<u8>::MIN;
288static MAX_NZ_U8: NonZero<u8> = NonZero::<u8>::MAX;
289
290static MIN_I8: i8 = i8::MIN;
291static MAX_I8: i8 = i8::MAX;
292static MIN_NZ_I8: NonZero<i8> = NonZero::<i8>::MIN;
293static MAX_NZ_I8: NonZero<i8> = NonZero::<i8>::MAX;
294
295static MIN_U16: u16 = u16::MIN;
296static MAX_U16: u16 = u16::MAX;
297static MIN_NZ_U16: NonZero<u16> = NonZero::<u16>::MIN;
298static MAX_NZ_U16: NonZero<u16> = NonZero::<u16>::MAX;
299
300static MIN_I16: i16 = i16::MIN;
301static MAX_I16: i16 = i16::MAX;
302static MIN_NZ_I16: NonZero<i16> = NonZero::<i16>::MIN;
303static MAX_NZ_I16: NonZero<i16> = NonZero::<i16>::MAX;
304
305static MIN_U32: u32 = u32::MIN;
306static MAX_U32: u32 = u32::MAX;
307static MIN_NZ_U32: NonZero<u32> = NonZero::<u32>::MIN;
308static MAX_NZ_U32: NonZero<u32> = NonZero::<u32>::MAX;
309
310static MIN_I32: i32 = i32::MIN;
311static MAX_I32: i32 = i32::MAX;
312static MIN_NZ_I32: NonZero<i32> = NonZero::<i32>::MIN;
313static MAX_NZ_I32: NonZero<i32> = NonZero::<i32>::MAX;
314
315static MIN_U64: u64 = u64::MIN;
316static MAX_U64: u64 = u64::MAX;
317static MIN_NZ_U64: NonZero<u64> = NonZero::<u64>::MIN;
318static MAX_NZ_U64: NonZero<u64> = NonZero::<u64>::MAX;
319
320static MIN_I64: i64 = i64::MIN;
321static MAX_I64: i64 = i64::MAX;
322static MIN_NZ_I64: NonZero<i64> = NonZero::<i64>::MIN;
323static MAX_NZ_I64: NonZero<i64> = NonZero::<i64>::MAX;
324
325static MIN_U128: u128 = u128::MIN;
326static MAX_U128: u128 = u128::MAX;
327static MIN_NZ_U128: NonZero<u128> = NonZero::<u128>::MIN;
328static MAX_NZ_U128: NonZero<u128> = NonZero::<u128>::MAX;
329
330static MIN_I128: i128 = i128::MIN;
331static MAX_I128: i128 = i128::MAX;
332static MIN_NZ_I128: NonZero<i128> = NonZero::<i128>::MIN;
333static MAX_NZ_I128: NonZero<i128> = NonZero::<i128>::MAX;
334
335static MIN_USIZE: usize = usize::MIN;
336static MAX_USIZE: usize = usize::MAX;
337static MIN_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MIN;
338static MAX_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MAX;
339
340static MIN_ISIZE: isize = isize::MIN;
341static MAX_ISIZE: isize = isize::MAX;
342static MIN_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MIN;
343static MAX_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MAX;
344
345impl_facet_for_integer!(
346    u8,
347    &const {
348        ScalarAffinity::number()
349            .unsigned_integer(8)
350            .min(PtrConst::new(&raw const MIN_U8))
351            .max(PtrConst::new(&raw const MAX_U8))
352            .build()
353    },
354    &const {
355        ScalarAffinity::number()
356            .unsigned_integer(8)
357            .min(PtrConst::new(&raw const MIN_NZ_U8))
358            .max(PtrConst::new(&raw const MAX_NZ_U8))
359            .build()
360    }
361);
362
363impl_facet_for_integer!(
364    i8,
365    &const {
366        ScalarAffinity::number()
367            .signed_integer(8)
368            .min(PtrConst::new(&raw const MIN_I8))
369            .max(PtrConst::new(&raw const MAX_I8))
370            .build()
371    },
372    &const {
373        ScalarAffinity::number()
374            .signed_integer(8)
375            .min(PtrConst::new(&raw const MIN_NZ_I8))
376            .max(PtrConst::new(&raw const MAX_NZ_I8))
377            .build()
378    }
379);
380
381impl_facet_for_integer!(
382    u16,
383    &const {
384        ScalarAffinity::number()
385            .unsigned_integer(16)
386            .min(PtrConst::new(&raw const MIN_U16))
387            .max(PtrConst::new(&raw const MAX_U16))
388            .build()
389    },
390    &const {
391        ScalarAffinity::number()
392            .unsigned_integer(16)
393            .min(PtrConst::new(&raw const MIN_NZ_U16))
394            .max(PtrConst::new(&raw const MAX_NZ_U16))
395            .build()
396    }
397);
398
399impl_facet_for_integer!(
400    i16,
401    &const {
402        ScalarAffinity::number()
403            .signed_integer(16)
404            .min(PtrConst::new(&raw const MIN_I16))
405            .max(PtrConst::new(&raw const MAX_I16))
406            .build()
407    },
408    &const {
409        ScalarAffinity::number()
410            .signed_integer(16)
411            .min(PtrConst::new(&raw const MIN_NZ_I16))
412            .max(PtrConst::new(&raw const MAX_NZ_I16))
413            .build()
414    }
415);
416
417impl_facet_for_integer!(
418    u32,
419    &const {
420        ScalarAffinity::number()
421            .unsigned_integer(32)
422            .min(PtrConst::new(&raw const MIN_U32))
423            .max(PtrConst::new(&raw const MAX_U32))
424            .build()
425    },
426    &const {
427        ScalarAffinity::number()
428            .unsigned_integer(32)
429            .min(PtrConst::new(&raw const MIN_NZ_U32))
430            .max(PtrConst::new(&raw const MAX_NZ_U32))
431            .build()
432    }
433);
434
435impl_facet_for_integer!(
436    i32,
437    &const {
438        ScalarAffinity::number()
439            .signed_integer(32)
440            .min(PtrConst::new(&raw const MIN_I32))
441            .max(PtrConst::new(&raw const MAX_I32))
442            .build()
443    },
444    &const {
445        ScalarAffinity::number()
446            .signed_integer(32)
447            .min(PtrConst::new(&raw const MIN_NZ_I32))
448            .max(PtrConst::new(&raw const MAX_NZ_I32))
449            .build()
450    }
451);
452
453impl_facet_for_integer!(
454    u64,
455    &const {
456        ScalarAffinity::number()
457            .unsigned_integer(64)
458            .min(PtrConst::new(&raw const MIN_U64))
459            .max(PtrConst::new(&raw const MAX_U64))
460            .build()
461    },
462    &const {
463        ScalarAffinity::number()
464            .unsigned_integer(64)
465            .min(PtrConst::new(&raw const MIN_NZ_U64))
466            .max(PtrConst::new(&raw const MAX_NZ_U64))
467            .build()
468    }
469);
470
471impl_facet_for_integer!(
472    i64,
473    &const {
474        ScalarAffinity::number()
475            .signed_integer(64)
476            .min(PtrConst::new(&raw const MIN_I64))
477            .max(PtrConst::new(&raw const MAX_I64))
478            .build()
479    },
480    &const {
481        ScalarAffinity::number()
482            .signed_integer(64)
483            .min(PtrConst::new(&raw const MIN_NZ_I64))
484            .max(PtrConst::new(&raw const MAX_NZ_I64))
485            .build()
486    }
487);
488
489impl_facet_for_integer!(
490    u128,
491    &const {
492        ScalarAffinity::number()
493            .unsigned_integer(128)
494            .min(PtrConst::new(&raw const MIN_U128))
495            .max(PtrConst::new(&raw const MAX_U128))
496            .build()
497    },
498    &const {
499        ScalarAffinity::number()
500            .unsigned_integer(128)
501            .min(PtrConst::new(&raw const MIN_NZ_U128))
502            .max(PtrConst::new(&raw const MAX_NZ_U128))
503            .build()
504    }
505);
506
507impl_facet_for_integer!(
508    i128,
509    &const {
510        ScalarAffinity::number()
511            .signed_integer(128)
512            .min(PtrConst::new(&raw const MIN_I128))
513            .max(PtrConst::new(&raw const MAX_I128))
514            .build()
515    },
516    &const {
517        ScalarAffinity::number()
518            .signed_integer(128)
519            .min(PtrConst::new(&raw const MIN_NZ_I128))
520            .max(PtrConst::new(&raw const MAX_NZ_I128))
521            .build()
522    }
523);
524
525impl_facet_for_integer!(
526    usize,
527    &const {
528        ScalarAffinity::number()
529            .pointer_sized_unsigned_integer()
530            .min(PtrConst::new(&raw const MIN_USIZE))
531            .max(PtrConst::new(&raw const MAX_USIZE))
532            .build()
533    },
534    &const {
535        ScalarAffinity::number()
536            .pointer_sized_unsigned_integer()
537            .min(PtrConst::new(&raw const MIN_NZ_USIZE))
538            .max(PtrConst::new(&raw const MAX_NZ_USIZE))
539            .build()
540    }
541);
542
543impl_facet_for_integer!(
544    isize,
545    &const {
546        ScalarAffinity::number()
547            .pointer_sized_signed_integer()
548            .min(PtrConst::new(&raw const MIN_ISIZE))
549            .max(PtrConst::new(&raw const MAX_ISIZE))
550            .build()
551    },
552    &const {
553        ScalarAffinity::number()
554            .pointer_sized_signed_integer()
555            .min(PtrConst::new(&raw const MIN_NZ_ISIZE))
556            .max(PtrConst::new(&raw const MAX_NZ_ISIZE))
557            .build()
558    }
559);
560// Constants for f32
561static MIN_F32: f32 = f32::MIN;
562static MAX_F32: f32 = f32::MAX;
563static POSITIVE_INFINITY_F32: f32 = f32::INFINITY;
564static NEGATIVE_INFINITY_F32: f32 = f32::NEG_INFINITY;
565static NAN_F32: f32 = f32::NAN;
566static POSITIVE_ZERO_F32: f32 = 0.0f32;
567static NEGATIVE_ZERO_F32: f32 = -0.0f32;
568static EPSILON_F32: f32 = f32::EPSILON;
569
570// Constants for f64
571static MIN_F64: f64 = f64::MIN;
572static MAX_F64: f64 = f64::MAX;
573static POSITIVE_INFINITY_F64: f64 = f64::INFINITY;
574static NEGATIVE_INFINITY_F64: f64 = f64::NEG_INFINITY;
575static NAN_F64: f64 = f64::NAN;
576static POSITIVE_ZERO_F64: f64 = 0.0f64;
577static NEGATIVE_ZERO_F64: f64 = -0.0f64;
578static EPSILON_F64: f64 = f64::EPSILON;
579
580unsafe impl Facet<'_> for f32 {
581    const VTABLE: &'static ValueVTable =
582        &const { value_vtable!(f32, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier)) };
583
584    const SHAPE: &'static Shape<'static> = &const {
585        Shape::builder_for_sized::<Self>()
586            .type_identifier("f32")
587            .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
588            .def(Def::Scalar(
589                ScalarDef::builder()
590                    .affinity(
591                        &const {
592                            ScalarAffinity::number()
593                                .float(1, 8, f32::MANTISSA_DIGITS as usize - 1, false)
594                                .min(PtrConst::new(&raw const MIN_F32))
595                                .max(PtrConst::new(&raw const MAX_F32))
596                                .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F32))
597                                .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F32))
598                                .nan_sample(PtrConst::new(&raw const NAN_F32))
599                                .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F32))
600                                .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F32))
601                                .epsilon(PtrConst::new(&raw const EPSILON_F32))
602                                .build()
603                        },
604                    )
605                    .build(),
606            ))
607            .build()
608    };
609}
610
611unsafe impl Facet<'_> for f64 {
612    const VTABLE: &'static ValueVTable = &const {
613        let mut vtable =
614            value_vtable!(f64, |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier));
615
616        {
617            let vtable_sized = vtable.sized_mut().unwrap();
618            vtable_sized.try_from = || {
619                Some(|source, source_shape, dest| {
620                    if source_shape == Self::SHAPE {
621                        return Ok(unsafe { dest.copy_from(source, source_shape)? });
622                    }
623                    if source_shape == u64::SHAPE {
624                        let value: u64 = *unsafe { source.get::<u64>() };
625                        let converted: f64 = value as f64;
626                        return Ok(unsafe { dest.put::<f64>(converted) });
627                    }
628                    if source_shape == i64::SHAPE {
629                        let value: i64 = *unsafe { source.get::<i64>() };
630                        let converted: f64 = value as f64;
631                        return Ok(unsafe { dest.put::<f64>(converted) });
632                    }
633                    if source_shape == f32::SHAPE {
634                        let value: f32 = *unsafe { source.get::<f32>() };
635                        let converted: f64 = value as f64;
636                        return Ok(unsafe { dest.put::<f64>(converted) });
637                    }
638                    Err(TryFromError::UnsupportedSourceShape {
639                        src_shape: source_shape,
640                        expected: &[Self::SHAPE, u64::SHAPE, i64::SHAPE, f32::SHAPE],
641                    })
642                })
643            };
644        }
645
646        vtable
647    };
648
649    const SHAPE: &'static Shape<'static> = &const {
650        Shape::builder_for_sized::<Self>()
651            .type_identifier("f64")
652            .ty(Type::Primitive(PrimitiveType::Numeric(NumericType::Float)))
653            .def(Def::Scalar(
654                ScalarDef::builder()
655                    .affinity(
656                        &const {
657                            ScalarAffinity::number()
658                                .float(1, 11, f64::MANTISSA_DIGITS as usize - 1, false)
659                                .min(PtrConst::new(&raw const MIN_F64))
660                                .max(PtrConst::new(&raw const MAX_F64))
661                                .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F64))
662                                .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F64))
663                                .nan_sample(PtrConst::new(&raw const NAN_F64))
664                                .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F64))
665                                .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F64))
666                                .epsilon(PtrConst::new(&raw const EPSILON_F64))
667                                .build()
668                        },
669                    )
670                    .build(),
671            ))
672            .build()
673    };
674}
675
676unsafe impl Facet<'_> for core::net::SocketAddr {
677    const VTABLE: &'static ValueVTable = &const {
678        value_vtable!(core::net::SocketAddr, |f, _opts| write!(
679            f,
680            "{}",
681            Self::SHAPE.type_identifier
682        ))
683    };
684
685    const SHAPE: &'static Shape<'static> = &const {
686        Shape::builder_for_sized::<Self>()
687            .type_identifier("SocketAddr")
688            .ty(Type::User(UserType::Opaque))
689            .def(Def::Scalar(
690                ScalarDef::builder()
691                    .affinity(&const { ScalarAffinity::socket_addr().build() })
692                    .build(),
693            ))
694            .build()
695    };
696}
697
698unsafe impl Facet<'_> for core::net::IpAddr {
699    const VTABLE: &'static ValueVTable = &const {
700        value_vtable!(core::net::IpAddr, |f, _opts| write!(
701            f,
702            "{}",
703            Self::SHAPE.type_identifier
704        ))
705    };
706
707    const SHAPE: &'static Shape<'static> = &const {
708        Shape::builder_for_sized::<Self>()
709            .type_identifier("IpAddr")
710            .ty(Type::User(UserType::Opaque))
711            .def(Def::Scalar(
712                ScalarDef::builder()
713                    .affinity(&const { ScalarAffinity::ip_addr().build() })
714                    .build(),
715            ))
716            .build()
717    };
718}
719
720unsafe impl Facet<'_> for core::net::Ipv4Addr {
721    const VTABLE: &'static ValueVTable = &const {
722        value_vtable!(core::net::Ipv4Addr, |f, _opts| write!(
723            f,
724            "{}",
725            Self::SHAPE.type_identifier
726        ))
727    };
728
729    const SHAPE: &'static Shape<'static> = &const {
730        Shape::builder_for_sized::<Self>()
731            .type_identifier("Ipv4Addr")
732            .ty(Type::User(UserType::Opaque))
733            .def(Def::Scalar(
734                ScalarDef::builder()
735                    .affinity(&const { ScalarAffinity::ip_addr().build() })
736                    .build(),
737            ))
738            .build()
739    };
740}
741
742unsafe impl Facet<'_> for core::net::Ipv6Addr {
743    const VTABLE: &'static ValueVTable = &const {
744        value_vtable!(core::net::Ipv6Addr, |f, _opts| write!(
745            f,
746            "{}",
747            Self::SHAPE.type_identifier
748        ))
749    };
750
751    const SHAPE: &'static Shape<'static> = &const {
752        Shape::builder_for_sized::<Self>()
753            .type_identifier("Ipv6Addr")
754            .ty(Type::User(UserType::Opaque))
755            .def(Def::Scalar(
756                ScalarDef::builder()
757                    .affinity(&const { ScalarAffinity::ip_addr().build() })
758                    .build(),
759            ))
760            .build()
761    };
762}