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