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