facet_core/_trait/impls/
scalar_impls.rs

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