facet_core/_trait/impls/
scalar_impls.rs

1use crate::value_vtable;
2use crate::*;
3use core::alloc::Layout;
4use core::num::NonZero;
5use core::option::Option;
6use typeid::ConstTypeId;
7
8unsafe impl Facet for ConstTypeId {
9    const SHAPE: &'static Shape = &const {
10        Shape::builder()
11            .id(ConstTypeId::of::<ConstTypeId>())
12            .layout(Layout::new::<Self>())
13            .def(Def::Scalar(
14                ScalarDef::builder()
15                    .affinity(ScalarAffinity::opaque().build())
16                    .build(),
17            ))
18            .vtable(value_vtable!((), |f, _opts| write!(f, "ConstTypeId")))
19            .build()
20    };
21}
22
23unsafe impl Facet for () {
24    const SHAPE: &'static Shape = &const {
25        Shape::builder()
26            .id(ConstTypeId::of::<()>())
27            .layout(Layout::new::<Self>())
28            .def(Def::Scalar(
29                ScalarDef::builder()
30                    .affinity(ScalarAffinity::empty().build())
31                    .build(),
32            ))
33            .vtable(value_vtable!((), |f, _opts| write!(f, "()")))
34            .build()
35    };
36}
37
38unsafe impl<T: ?Sized> Facet for core::marker::PhantomData<T> {
39    const SHAPE: &'static Shape = &const {
40        Shape::builder()
41            .id(ConstTypeId::of::<Self>())
42            .layout(Layout::new::<Self>())
43            .def(Def::Scalar(
44                ScalarDef::builder()
45                    .affinity(ScalarAffinity::empty().build())
46                    .build(),
47            ))
48            .vtable(value_vtable!((), |f, _opts| write!(f, "PhantomData")))
49            .build()
50    };
51}
52
53#[cfg(feature = "alloc")]
54unsafe impl Facet for alloc::string::String {
55    const SHAPE: &'static Shape = &const {
56        Shape::builder()
57            .id(ConstTypeId::of::<alloc::string::String>())
58            .layout(Layout::new::<Self>())
59            .def(Def::Scalar(
60                ScalarDef::builder()
61                    // `String` is always on the heap
62                    .affinity(ScalarAffinity::string().max_inline_length(0).build())
63                    .build(),
64            ))
65            .vtable(value_vtable!(alloc::string::String, |f, _opts| write!(
66                f,
67                "String"
68            )))
69            .build()
70    };
71}
72
73unsafe impl Facet for char {
74    const SHAPE: &'static Shape = &const {
75        Shape::builder()
76            .id(ConstTypeId::of::<char>())
77            .layout(Layout::new::<Self>())
78            .def(Def::Scalar(
79                ScalarDef::builder()
80                    .affinity(ScalarAffinity::char().build())
81                    .build(),
82            ))
83            .vtable(value_vtable!(char, |f, _opts| write!(f, "char")))
84            .build()
85    };
86}
87
88unsafe impl Facet for &str {
89    const SHAPE: &'static Shape = &const {
90        Shape::builder()
91            .id(ConstTypeId::of::<&str>())
92            .layout(Layout::new::<Self>())
93            .def(Def::Scalar(
94                ScalarDef::builder()
95                    .affinity(ScalarAffinity::string().build())
96                    .build(),
97            ))
98            .vtable(value_vtable!(&str, |f, _opts| write!(f, "&str")))
99            .build()
100    };
101}
102
103#[cfg(feature = "alloc")]
104unsafe impl Facet for alloc::borrow::Cow<'_, str> {
105    const SHAPE: &'static Shape = &const {
106        Shape::builder()
107            .id(ConstTypeId::of::<alloc::borrow::Cow<'_, str>>())
108            .layout(Layout::new::<Self>())
109            .def(Def::Scalar(
110                ScalarDef::builder()
111                    .affinity(ScalarAffinity::string().build())
112                    .build(),
113            ))
114            .vtable(value_vtable!(
115                alloc::borrow::Cow<'_, str>,
116                |f, _opts| write!(f, "Cow<'_, str>")
117            ))
118            .build()
119    };
120}
121
122unsafe impl Facet for bool {
123    const SHAPE: &'static Shape = &const {
124        Shape::builder()
125            .id(ConstTypeId::of::<bool>())
126            .layout(Layout::new::<Self>())
127            .def(Def::Scalar(
128                ScalarDef::builder()
129                    .affinity(ScalarAffinity::boolean().build())
130                    .build(),
131            ))
132            .vtable(value_vtable!(bool, |f, _opts| write!(f, "bool")))
133            .build()
134    };
135}
136
137macro_rules! impl_facet_for_integer {
138    ($type:ty, $affinity:expr, $nz_affinity:expr) => {
139        unsafe impl Facet for $type {
140            const SHAPE: &'static Shape = &const {
141                Shape::builder()
142                    .id(ConstTypeId::of::<Self>())
143                    .layout(Layout::new::<Self>())
144                    .def(Def::Scalar(
145                        ScalarDef::builder().affinity($affinity).build(),
146                    ))
147                    .vtable(value_vtable!($type, |f, _opts| write!(
148                        f,
149                        stringify!($type)
150                    )))
151                    .build()
152            };
153        }
154
155        unsafe impl Facet for NonZero<$type> {
156            const SHAPE: &'static Shape = &const {
157                Shape::builder()
158                    .id(ConstTypeId::of::<Self>())
159                    .layout(Layout::new::<Self>())
160                    .def(Def::Scalar(
161                        ScalarDef::builder().affinity($nz_affinity).build(),
162                    ))
163                    .vtable(value_vtable!($type, |f, _opts| write!(
164                        f,
165                        "core::num::NonZero<{}>",
166                        stringify!($type)
167                    )))
168                    .build()
169            };
170        }
171    };
172}
173
174static MIN_U8: u8 = u8::MIN;
175static MAX_U8: u8 = u8::MAX;
176static MIN_NZ_U8: NonZero<u8> = NonZero::<u8>::MIN;
177static MAX_NZ_U8: NonZero<u8> = NonZero::<u8>::MAX;
178
179static MIN_I8: i8 = i8::MIN;
180static MAX_I8: i8 = i8::MAX;
181static MIN_NZ_I8: NonZero<i8> = NonZero::<i8>::MIN;
182static MAX_NZ_I8: NonZero<i8> = NonZero::<i8>::MAX;
183
184static MIN_U16: u16 = u16::MIN;
185static MAX_U16: u16 = u16::MAX;
186static MIN_NZ_U16: NonZero<u16> = NonZero::<u16>::MIN;
187static MAX_NZ_U16: NonZero<u16> = NonZero::<u16>::MAX;
188
189static MIN_I16: i16 = i16::MIN;
190static MAX_I16: i16 = i16::MAX;
191static MIN_NZ_I16: NonZero<i16> = NonZero::<i16>::MIN;
192static MAX_NZ_I16: NonZero<i16> = NonZero::<i16>::MAX;
193
194static MIN_U32: u32 = u32::MIN;
195static MAX_U32: u32 = u32::MAX;
196static MIN_NZ_U32: NonZero<u32> = NonZero::<u32>::MIN;
197static MAX_NZ_U32: NonZero<u32> = NonZero::<u32>::MAX;
198
199static MIN_I32: i32 = i32::MIN;
200static MAX_I32: i32 = i32::MAX;
201static MIN_NZ_I32: NonZero<i32> = NonZero::<i32>::MIN;
202static MAX_NZ_I32: NonZero<i32> = NonZero::<i32>::MAX;
203
204static MIN_U64: u64 = u64::MIN;
205static MAX_U64: u64 = u64::MAX;
206static MIN_NZ_U64: NonZero<u64> = NonZero::<u64>::MIN;
207static MAX_NZ_U64: NonZero<u64> = NonZero::<u64>::MAX;
208
209static MIN_I64: i64 = i64::MIN;
210static MAX_I64: i64 = i64::MAX;
211static MIN_NZ_I64: NonZero<i64> = NonZero::<i64>::MIN;
212static MAX_NZ_I64: NonZero<i64> = NonZero::<i64>::MAX;
213
214static MIN_U128: u128 = u128::MIN;
215static MAX_U128: u128 = u128::MAX;
216static MIN_NZ_U128: NonZero<u128> = NonZero::<u128>::MIN;
217static MAX_NZ_U128: NonZero<u128> = NonZero::<u128>::MAX;
218
219static MIN_I128: i128 = i128::MIN;
220static MAX_I128: i128 = i128::MAX;
221static MIN_NZ_I128: NonZero<i128> = NonZero::<i128>::MIN;
222static MAX_NZ_I128: NonZero<i128> = NonZero::<i128>::MAX;
223
224static MIN_USIZE: usize = usize::MIN;
225static MAX_USIZE: usize = usize::MAX;
226static MIN_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MIN;
227static MAX_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MAX;
228
229static MIN_ISIZE: isize = isize::MIN;
230static MAX_ISIZE: isize = isize::MAX;
231static MIN_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MIN;
232static MAX_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MAX;
233
234impl_facet_for_integer!(
235    u8,
236    ScalarAffinity::number()
237        .unsigned_integer(8)
238        .min(OpaqueConst::new(&raw const MIN_U8))
239        .max(OpaqueConst::new(&raw const MAX_U8))
240        .build(),
241    ScalarAffinity::number()
242        .unsigned_integer(8)
243        .min(OpaqueConst::new(&raw const MIN_NZ_U8))
244        .max(OpaqueConst::new(&raw const MAX_NZ_U8))
245        .build()
246);
247
248impl_facet_for_integer!(
249    i8,
250    ScalarAffinity::number()
251        .signed_integer(8)
252        .min(OpaqueConst::new(&raw const MIN_I8))
253        .max(OpaqueConst::new(&raw const MAX_I8))
254        .build(),
255    ScalarAffinity::number()
256        .signed_integer(8)
257        .min(OpaqueConst::new(&raw const MIN_NZ_I8))
258        .max(OpaqueConst::new(&raw const MAX_NZ_I8))
259        .build()
260);
261
262impl_facet_for_integer!(
263    u16,
264    ScalarAffinity::number()
265        .unsigned_integer(16)
266        .min(OpaqueConst::new(&raw const MIN_U16))
267        .max(OpaqueConst::new(&raw const MAX_U16))
268        .build(),
269    ScalarAffinity::number()
270        .unsigned_integer(16)
271        .min(OpaqueConst::new(&raw const MIN_NZ_U16))
272        .max(OpaqueConst::new(&raw const MAX_NZ_U16))
273        .build()
274);
275
276impl_facet_for_integer!(
277    i16,
278    ScalarAffinity::number()
279        .signed_integer(16)
280        .min(OpaqueConst::new(&raw const MIN_I16))
281        .max(OpaqueConst::new(&raw const MAX_I16))
282        .build(),
283    ScalarAffinity::number()
284        .signed_integer(16)
285        .min(OpaqueConst::new(&raw const MIN_NZ_I16))
286        .max(OpaqueConst::new(&raw const MAX_NZ_I16))
287        .build()
288);
289
290impl_facet_for_integer!(
291    u32,
292    ScalarAffinity::number()
293        .unsigned_integer(32)
294        .min(OpaqueConst::new(&raw const MIN_U32))
295        .max(OpaqueConst::new(&raw const MAX_U32))
296        .build(),
297    ScalarAffinity::number()
298        .unsigned_integer(32)
299        .min(OpaqueConst::new(&raw const MIN_NZ_U32))
300        .max(OpaqueConst::new(&raw const MAX_NZ_U32))
301        .build()
302);
303
304impl_facet_for_integer!(
305    i32,
306    ScalarAffinity::number()
307        .signed_integer(32)
308        .min(OpaqueConst::new(&raw const MIN_I32))
309        .max(OpaqueConst::new(&raw const MAX_I32))
310        .build(),
311    ScalarAffinity::number()
312        .signed_integer(32)
313        .min(OpaqueConst::new(&raw const MIN_NZ_I32))
314        .max(OpaqueConst::new(&raw const MAX_NZ_I32))
315        .build()
316);
317
318impl_facet_for_integer!(
319    u64,
320    ScalarAffinity::number()
321        .unsigned_integer(64)
322        .min(OpaqueConst::new(&raw const MIN_U64))
323        .max(OpaqueConst::new(&raw const MAX_U64))
324        .build(),
325    ScalarAffinity::number()
326        .unsigned_integer(64)
327        .min(OpaqueConst::new(&raw const MIN_NZ_U64))
328        .max(OpaqueConst::new(&raw const MAX_NZ_U64))
329        .build()
330);
331
332impl_facet_for_integer!(
333    i64,
334    ScalarAffinity::number()
335        .signed_integer(64)
336        .min(OpaqueConst::new(&raw const MIN_I64))
337        .max(OpaqueConst::new(&raw const MAX_I64))
338        .build(),
339    ScalarAffinity::number()
340        .signed_integer(64)
341        .min(OpaqueConst::new(&raw const MIN_NZ_I64))
342        .max(OpaqueConst::new(&raw const MAX_NZ_I64))
343        .build()
344);
345
346impl_facet_for_integer!(
347    u128,
348    ScalarAffinity::number()
349        .unsigned_integer(128)
350        .min(OpaqueConst::new(&raw const MIN_U128))
351        .max(OpaqueConst::new(&raw const MAX_U128))
352        .build(),
353    ScalarAffinity::number()
354        .unsigned_integer(128)
355        .min(OpaqueConst::new(&raw const MIN_NZ_U128))
356        .max(OpaqueConst::new(&raw const MAX_NZ_U128))
357        .build()
358);
359
360impl_facet_for_integer!(
361    i128,
362    ScalarAffinity::number()
363        .signed_integer(128)
364        .min(OpaqueConst::new(&raw const MIN_I128))
365        .max(OpaqueConst::new(&raw const MAX_I128))
366        .build(),
367    ScalarAffinity::number()
368        .signed_integer(128)
369        .min(OpaqueConst::new(&raw const MIN_NZ_I128))
370        .max(OpaqueConst::new(&raw const MAX_NZ_I128))
371        .build()
372);
373
374impl_facet_for_integer!(
375    usize,
376    ScalarAffinity::number()
377        .unsigned_integer(core::mem::size_of::<usize>() * 8)
378        .min(OpaqueConst::new(&raw const MIN_USIZE))
379        .max(OpaqueConst::new(&raw const MAX_USIZE))
380        .build(),
381    ScalarAffinity::number()
382        .unsigned_integer(core::mem::size_of::<usize>() * 8)
383        .min(OpaqueConst::new(&raw const MIN_NZ_USIZE))
384        .max(OpaqueConst::new(&raw const MAX_NZ_USIZE))
385        .build()
386);
387
388impl_facet_for_integer!(
389    isize,
390    ScalarAffinity::number()
391        .signed_integer(core::mem::size_of::<isize>() * 8)
392        .min(OpaqueConst::new(&raw const MIN_ISIZE))
393        .max(OpaqueConst::new(&raw const MAX_ISIZE))
394        .build(),
395    ScalarAffinity::number()
396        .signed_integer(core::mem::size_of::<isize>() * 8)
397        .min(OpaqueConst::new(&raw const MIN_NZ_ISIZE))
398        .max(OpaqueConst::new(&raw const MAX_NZ_ISIZE))
399        .build()
400);
401
402// Constants for f32
403static MIN_F32: f32 = f32::MIN;
404static MAX_F32: f32 = f32::MAX;
405static POSITIVE_INFINITY_F32: f32 = f32::INFINITY;
406static NEGATIVE_INFINITY_F32: f32 = f32::NEG_INFINITY;
407static NAN_F32: f32 = f32::NAN;
408static POSITIVE_ZERO_F32: f32 = 0.0f32;
409static NEGATIVE_ZERO_F32: f32 = -0.0f32;
410
411// Constants for f64
412static MIN_F64: f64 = f64::MIN;
413static MAX_F64: f64 = f64::MAX;
414static POSITIVE_INFINITY_F64: f64 = f64::INFINITY;
415static NEGATIVE_INFINITY_F64: f64 = f64::NEG_INFINITY;
416static NAN_F64: f64 = f64::NAN;
417static POSITIVE_ZERO_F64: f64 = 0.0f64;
418static NEGATIVE_ZERO_F64: f64 = -0.0f64;
419
420unsafe impl Facet for f32 {
421    const SHAPE: &'static Shape = &const {
422        Shape::builder()
423            .id(ConstTypeId::of::<f32>())
424            .layout(Layout::new::<Self>())
425            .def(Def::Scalar(
426                ScalarDef::builder()
427                    .affinity(
428                        ScalarAffinity::number()
429                            .float(1, 8, 23)
430                            .min(OpaqueConst::new(&raw const MIN_F32))
431                            .max(OpaqueConst::new(&raw const MAX_F32))
432                            .positive_infinity(OpaqueConst::new(&raw const POSITIVE_INFINITY_F32))
433                            .negative_infinity(OpaqueConst::new(&raw const NEGATIVE_INFINITY_F32))
434                            .nan_sample(OpaqueConst::new(&raw const NAN_F32))
435                            .positive_zero(OpaqueConst::new(&raw const POSITIVE_ZERO_F32))
436                            .negative_zero(OpaqueConst::new(&raw const NEGATIVE_ZERO_F32))
437                            .build(),
438                    )
439                    .build(),
440            ))
441            .vtable(value_vtable!(f32, |f, _opts| write!(f, "f32")))
442            .build()
443    };
444}
445
446unsafe impl Facet for f64 {
447    const SHAPE: &'static Shape = &const {
448        Shape::builder()
449            .id(ConstTypeId::of::<f64>())
450            .layout(Layout::new::<Self>())
451            .def(Def::Scalar(
452                ScalarDef::builder()
453                    .affinity(
454                        ScalarAffinity::number()
455                            .float(1, 11, 52)
456                            .min(OpaqueConst::new(&raw const MIN_F64))
457                            .max(OpaqueConst::new(&raw const MAX_F64))
458                            .positive_infinity(OpaqueConst::new(&raw const POSITIVE_INFINITY_F64))
459                            .negative_infinity(OpaqueConst::new(&raw const NEGATIVE_INFINITY_F64))
460                            .nan_sample(OpaqueConst::new(&raw const NAN_F64))
461                            .positive_zero(OpaqueConst::new(&raw const POSITIVE_ZERO_F64))
462                            .negative_zero(OpaqueConst::new(&raw const NEGATIVE_ZERO_F64))
463                            .build(),
464                    )
465                    .build(),
466            ))
467            .vtable(value_vtable!(f64, |f, _opts| write!(f, "f64")))
468            .build()
469    };
470}
471
472unsafe impl Facet for core::net::SocketAddr {
473    const SHAPE: &'static Shape = &const {
474        Shape::builder()
475            .id(ConstTypeId::of::<Self>())
476            .layout(Layout::new::<Self>())
477            .def(Def::Scalar(
478                ScalarDef::builder()
479                    .affinity(ScalarAffinity::socket_addr().build())
480                    .build(),
481            ))
482            .vtable(value_vtable!(core::net::SocketAddr, |f, _opts| write!(
483                f,
484                "SocketAddr"
485            )))
486            .build()
487    };
488}
489
490unsafe impl Facet for core::net::IpAddr {
491    const SHAPE: &'static Shape = &const {
492        Shape::builder()
493            .id(ConstTypeId::of::<Self>())
494            .layout(Layout::new::<Self>())
495            .def(Def::Scalar(
496                ScalarDef::builder()
497                    .affinity(ScalarAffinity::ip_addr().build())
498                    .build(),
499            ))
500            .vtable(value_vtable!(core::net::IpAddr, |f, _opts| write!(
501                f,
502                "IpAddr"
503            )))
504            .build()
505    };
506}
507
508unsafe impl Facet for core::net::Ipv4Addr {
509    const SHAPE: &'static Shape = &const {
510        Shape::builder()
511            .id(ConstTypeId::of::<Self>())
512            .layout(Layout::new::<Self>())
513            .def(Def::Scalar(
514                ScalarDef::builder()
515                    .affinity(ScalarAffinity::ip_addr().build())
516                    .build(),
517            ))
518            .vtable(value_vtable!(core::net::Ipv4Addr, |f, _opts| write!(
519                f,
520                "Ipv4Addr"
521            )))
522            .build()
523    };
524}
525
526unsafe impl Facet for core::net::Ipv6Addr {
527    const SHAPE: &'static Shape = &const {
528        Shape::builder()
529            .id(ConstTypeId::of::<Self>())
530            .layout(Layout::new::<Self>())
531            .def(Def::Scalar(
532                ScalarDef::builder()
533                    .affinity(ScalarAffinity::ip_addr().build())
534                    .build(),
535            ))
536            .vtable(value_vtable!(core::net::Ipv6Addr, |f, _opts| write!(
537                f,
538                "Ipv6Addr"
539            )))
540            .build()
541    };
542}
543
544unsafe impl<T: Facet> Facet for Option<T> {
545    const SHAPE: &'static Shape = &const {
546        Shape::builder()
547            .id(ConstTypeId::of::<Self>())
548            .layout(Layout::new::<Self>())
549            .def(Def::Option(
550                OptionDef::builder()
551                    .t(T::SHAPE)
552                    .vtable(
553                        const {
554                            &OptionVTable {
555                                is_some_fn: |option| unsafe {
556                                    option.as_ref::<Option<T>>().is_some()
557                                },
558                                get_value_fn: |option| unsafe {
559                                    option
560                                        .as_ref::<Option<T>>()
561                                        .as_ref()
562                                        .map(|t| OpaqueConst::new(t as *const T))
563                                },
564                                init_some_fn: |option, value| unsafe {
565                                    option.put(Option::Some(value.read::<T>()))
566                                },
567                                init_none_fn: |option| unsafe { option.put(<Option<T>>::None) },
568                                replace_with_fn: |option, value| unsafe {
569                                    let option = option.as_mut::<Option<T>>();
570                                    match value {
571                                        Some(value) => option.replace(value.read::<T>()),
572                                        None => option.take(),
573                                    };
574                                },
575                            }
576                        },
577                    )
578                    .build(),
579            ))
580            .vtable(value_vtable!(core::option::Option<T>, |f, _opts| write!(
581                f,
582                "Option"
583            )))
584            .build()
585    };
586}