1use crate::value_vtable;
2use crate::*;
3use core::alloc::Layout;
4use core::num::NonZero;
5use typeid::ConstTypeId;
6
7unsafe impl Facet<'_> for ConstTypeId {
8 const SHAPE: &'static Shape = &const {
9 Shape::builder()
10 .id(ConstTypeId::of::<Self>())
11 .layout(Layout::new::<Self>())
12 .def(Def::Scalar(
13 ScalarDef::builder()
14 .affinity(ScalarAffinity::opaque().build())
15 .build(),
16 ))
17 .vtable(value_vtable!((), |f, _opts| write!(f, "ConstTypeId")))
18 .build()
19 };
20}
21
22unsafe impl Facet<'_> for () {
23 const SHAPE: &'static Shape = &const {
24 Shape::builder()
25 .id(ConstTypeId::of::<Self>())
26 .layout(Layout::new::<Self>())
27 .def(Def::Scalar(
28 ScalarDef::builder()
29 .affinity(ScalarAffinity::empty().build())
30 .build(),
31 ))
32 .vtable(value_vtable!((), |f, _opts| write!(f, "()")))
33 .build()
34 };
35}
36
37unsafe impl<'a, T: ?Sized + 'a> Facet<'a> for core::marker::PhantomData<T> {
38 const SHAPE: &'static Shape = &const {
39 Shape::builder()
40 .id(ConstTypeId::of::<Self>())
41 .layout(Layout::new::<Self>())
42 .def(Def::Scalar(
43 ScalarDef::builder()
44 .affinity(ScalarAffinity::empty().build())
45 .build(),
46 ))
47 .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::<Self>())
58 .layout(Layout::new::<Self>())
59 .def(Def::Scalar(
60 ScalarDef::builder()
61 .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::<Self>())
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<'a> Facet<'a> for &'a str {
89 const SHAPE: &'static Shape = &const {
90 Shape::builder()
91 .id(ConstTypeId::of::<Self>())
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<'a> Facet<'a> for alloc::borrow::Cow<'a, str> {
105 const SHAPE: &'static Shape = &const {
106 Shape::builder()
107 .id(ConstTypeId::of::<Self>())
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::<Self>())
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<'a> Facet<'a> 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(
148 &const {
149 let mut vtable = value_vtable_inner!($type, |f, _opts| write!(
150 f,
151 "{}",
152 stringify!($type)
153 ));
154
155 vtable.try_from = Some(|source, source_shape, dest| {
156 if source_shape == Self::SHAPE {
157 return Ok(unsafe { dest.copy_from(source, source_shape) });
158 }
159 if source_shape == u64::SHAPE {
160 let value: u64 = *unsafe { source.get::<u64>() };
161 let converted: $type = value as $type;
162 return Ok(unsafe { dest.put::<$type>(converted) });
163 }
164 if source_shape == i64::SHAPE {
165 let value: i64 = *unsafe { source.get::<i64>() };
166 let converted: $type = value as $type;
167 return Ok(unsafe { dest.put::<$type>(converted) });
168 }
169 if source_shape == f64::SHAPE {
170 let value: f64 = *unsafe { source.get::<f64>() };
171 let converted: $type = value as $type;
172 return Ok(unsafe { dest.put::<$type>(converted) });
173 }
174 Err(TryFromError::Incompatible)
175 });
176
177 vtable
178 },
179 )
180 .build()
181 };
182 }
183
184 unsafe impl<'a> Facet<'a> for NonZero<$type> {
185 const SHAPE: &'static Shape = &const {
186 Shape::builder()
187 .id(ConstTypeId::of::<Self>())
188 .layout(Layout::new::<Self>())
189 .def(Def::Scalar(
190 ScalarDef::builder().affinity($nz_affinity).build(),
191 ))
192 .vtable(
193 &const {
194 let mut vtable = value_vtable_inner!($type, |f, _opts| write!(
195 f,
196 "NonZero<{}>",
197 stringify!($type)
198 ));
199
200 vtable.try_from = Some(|source, source_shape, dest| {
201 if source_shape == Self::SHAPE {
202 return Ok(unsafe { dest.copy_from(source, source_shape) });
203 }
204 if source_shape == <$type>::SHAPE {
205 let value: $type = *unsafe { source.get::<$type>() };
206 let nz = NonZero::new(value).ok_or_else(|| {
207 TryFromError::Generic("value must be non-zero")
208 })?;
209 return Ok(unsafe { dest.put::<NonZero<$type>>(nz) });
210 }
211 Err(TryFromError::Incompatible)
212 });
213
214 vtable
215 },
216 )
217 .build()
218 };
219 }
220 };
221}
222
223static MIN_U8: u8 = u8::MIN;
224static MAX_U8: u8 = u8::MAX;
225static MIN_NZ_U8: NonZero<u8> = NonZero::<u8>::MIN;
226static MAX_NZ_U8: NonZero<u8> = NonZero::<u8>::MAX;
227
228static MIN_I8: i8 = i8::MIN;
229static MAX_I8: i8 = i8::MAX;
230static MIN_NZ_I8: NonZero<i8> = NonZero::<i8>::MIN;
231static MAX_NZ_I8: NonZero<i8> = NonZero::<i8>::MAX;
232
233static MIN_U16: u16 = u16::MIN;
234static MAX_U16: u16 = u16::MAX;
235static MIN_NZ_U16: NonZero<u16> = NonZero::<u16>::MIN;
236static MAX_NZ_U16: NonZero<u16> = NonZero::<u16>::MAX;
237
238static MIN_I16: i16 = i16::MIN;
239static MAX_I16: i16 = i16::MAX;
240static MIN_NZ_I16: NonZero<i16> = NonZero::<i16>::MIN;
241static MAX_NZ_I16: NonZero<i16> = NonZero::<i16>::MAX;
242
243static MIN_U32: u32 = u32::MIN;
244static MAX_U32: u32 = u32::MAX;
245static MIN_NZ_U32: NonZero<u32> = NonZero::<u32>::MIN;
246static MAX_NZ_U32: NonZero<u32> = NonZero::<u32>::MAX;
247
248static MIN_I32: i32 = i32::MIN;
249static MAX_I32: i32 = i32::MAX;
250static MIN_NZ_I32: NonZero<i32> = NonZero::<i32>::MIN;
251static MAX_NZ_I32: NonZero<i32> = NonZero::<i32>::MAX;
252
253static MIN_U64: u64 = u64::MIN;
254static MAX_U64: u64 = u64::MAX;
255static MIN_NZ_U64: NonZero<u64> = NonZero::<u64>::MIN;
256static MAX_NZ_U64: NonZero<u64> = NonZero::<u64>::MAX;
257
258static MIN_I64: i64 = i64::MIN;
259static MAX_I64: i64 = i64::MAX;
260static MIN_NZ_I64: NonZero<i64> = NonZero::<i64>::MIN;
261static MAX_NZ_I64: NonZero<i64> = NonZero::<i64>::MAX;
262
263static MIN_U128: u128 = u128::MIN;
264static MAX_U128: u128 = u128::MAX;
265static MIN_NZ_U128: NonZero<u128> = NonZero::<u128>::MIN;
266static MAX_NZ_U128: NonZero<u128> = NonZero::<u128>::MAX;
267
268static MIN_I128: i128 = i128::MIN;
269static MAX_I128: i128 = i128::MAX;
270static MIN_NZ_I128: NonZero<i128> = NonZero::<i128>::MIN;
271static MAX_NZ_I128: NonZero<i128> = NonZero::<i128>::MAX;
272
273static MIN_USIZE: usize = usize::MIN;
274static MAX_USIZE: usize = usize::MAX;
275static MIN_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MIN;
276static MAX_NZ_USIZE: NonZero<usize> = NonZero::<usize>::MAX;
277
278static MIN_ISIZE: isize = isize::MIN;
279static MAX_ISIZE: isize = isize::MAX;
280static MIN_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MIN;
281static MAX_NZ_ISIZE: NonZero<isize> = NonZero::<isize>::MAX;
282
283impl_facet_for_integer!(
284 u8,
285 ScalarAffinity::number()
286 .unsigned_integer(8)
287 .min(PtrConst::new(&raw const MIN_U8))
288 .max(PtrConst::new(&raw const MAX_U8))
289 .build(),
290 ScalarAffinity::number()
291 .unsigned_integer(8)
292 .min(PtrConst::new(&raw const MIN_NZ_U8))
293 .max(PtrConst::new(&raw const MAX_NZ_U8))
294 .build()
295);
296
297impl_facet_for_integer!(
298 i8,
299 ScalarAffinity::number()
300 .signed_integer(8)
301 .min(PtrConst::new(&raw const MIN_I8))
302 .max(PtrConst::new(&raw const MAX_I8))
303 .build(),
304 ScalarAffinity::number()
305 .signed_integer(8)
306 .min(PtrConst::new(&raw const MIN_NZ_I8))
307 .max(PtrConst::new(&raw const MAX_NZ_I8))
308 .build()
309);
310
311impl_facet_for_integer!(
312 u16,
313 ScalarAffinity::number()
314 .unsigned_integer(16)
315 .min(PtrConst::new(&raw const MIN_U16))
316 .max(PtrConst::new(&raw const MAX_U16))
317 .build(),
318 ScalarAffinity::number()
319 .unsigned_integer(16)
320 .min(PtrConst::new(&raw const MIN_NZ_U16))
321 .max(PtrConst::new(&raw const MAX_NZ_U16))
322 .build()
323);
324
325impl_facet_for_integer!(
326 i16,
327 ScalarAffinity::number()
328 .signed_integer(16)
329 .min(PtrConst::new(&raw const MIN_I16))
330 .max(PtrConst::new(&raw const MAX_I16))
331 .build(),
332 ScalarAffinity::number()
333 .signed_integer(16)
334 .min(PtrConst::new(&raw const MIN_NZ_I16))
335 .max(PtrConst::new(&raw const MAX_NZ_I16))
336 .build()
337);
338
339impl_facet_for_integer!(
340 u32,
341 ScalarAffinity::number()
342 .unsigned_integer(32)
343 .min(PtrConst::new(&raw const MIN_U32))
344 .max(PtrConst::new(&raw const MAX_U32))
345 .build(),
346 ScalarAffinity::number()
347 .unsigned_integer(32)
348 .min(PtrConst::new(&raw const MIN_NZ_U32))
349 .max(PtrConst::new(&raw const MAX_NZ_U32))
350 .build()
351);
352
353impl_facet_for_integer!(
354 i32,
355 ScalarAffinity::number()
356 .signed_integer(32)
357 .min(PtrConst::new(&raw const MIN_I32))
358 .max(PtrConst::new(&raw const MAX_I32))
359 .build(),
360 ScalarAffinity::number()
361 .signed_integer(32)
362 .min(PtrConst::new(&raw const MIN_NZ_I32))
363 .max(PtrConst::new(&raw const MAX_NZ_I32))
364 .build()
365);
366
367impl_facet_for_integer!(
368 u64,
369 ScalarAffinity::number()
370 .unsigned_integer(64)
371 .min(PtrConst::new(&raw const MIN_U64))
372 .max(PtrConst::new(&raw const MAX_U64))
373 .build(),
374 ScalarAffinity::number()
375 .unsigned_integer(64)
376 .min(PtrConst::new(&raw const MIN_NZ_U64))
377 .max(PtrConst::new(&raw const MAX_NZ_U64))
378 .build()
379);
380
381impl_facet_for_integer!(
382 i64,
383 ScalarAffinity::number()
384 .signed_integer(64)
385 .min(PtrConst::new(&raw const MIN_I64))
386 .max(PtrConst::new(&raw const MAX_I64))
387 .build(),
388 ScalarAffinity::number()
389 .signed_integer(64)
390 .min(PtrConst::new(&raw const MIN_NZ_I64))
391 .max(PtrConst::new(&raw const MAX_NZ_I64))
392 .build()
393);
394
395impl_facet_for_integer!(
396 u128,
397 ScalarAffinity::number()
398 .unsigned_integer(128)
399 .min(PtrConst::new(&raw const MIN_U128))
400 .max(PtrConst::new(&raw const MAX_U128))
401 .build(),
402 ScalarAffinity::number()
403 .unsigned_integer(128)
404 .min(PtrConst::new(&raw const MIN_NZ_U128))
405 .max(PtrConst::new(&raw const MAX_NZ_U128))
406 .build()
407);
408
409impl_facet_for_integer!(
410 i128,
411 ScalarAffinity::number()
412 .signed_integer(128)
413 .min(PtrConst::new(&raw const MIN_I128))
414 .max(PtrConst::new(&raw const MAX_I128))
415 .build(),
416 ScalarAffinity::number()
417 .signed_integer(128)
418 .min(PtrConst::new(&raw const MIN_NZ_I128))
419 .max(PtrConst::new(&raw const MAX_NZ_I128))
420 .build()
421);
422
423impl_facet_for_integer!(
424 usize,
425 ScalarAffinity::number()
426 .unsigned_integer(core::mem::size_of::<usize>() * 8)
427 .min(PtrConst::new(&raw const MIN_USIZE))
428 .max(PtrConst::new(&raw const MAX_USIZE))
429 .build(),
430 ScalarAffinity::number()
431 .unsigned_integer(core::mem::size_of::<usize>() * 8)
432 .min(PtrConst::new(&raw const MIN_NZ_USIZE))
433 .max(PtrConst::new(&raw const MAX_NZ_USIZE))
434 .build()
435);
436
437impl_facet_for_integer!(
438 isize,
439 ScalarAffinity::number()
440 .signed_integer(core::mem::size_of::<isize>() * 8)
441 .min(PtrConst::new(&raw const MIN_ISIZE))
442 .max(PtrConst::new(&raw const MAX_ISIZE))
443 .build(),
444 ScalarAffinity::number()
445 .signed_integer(core::mem::size_of::<isize>() * 8)
446 .min(PtrConst::new(&raw const MIN_NZ_ISIZE))
447 .max(PtrConst::new(&raw const MAX_NZ_ISIZE))
448 .build()
449);
450
451static MIN_F32: f32 = f32::MIN;
453static MAX_F32: f32 = f32::MAX;
454static POSITIVE_INFINITY_F32: f32 = f32::INFINITY;
455static NEGATIVE_INFINITY_F32: f32 = f32::NEG_INFINITY;
456static NAN_F32: f32 = f32::NAN;
457static POSITIVE_ZERO_F32: f32 = 0.0f32;
458static NEGATIVE_ZERO_F32: f32 = -0.0f32;
459static EPSILON_F32: f32 = f32::EPSILON;
460
461static MIN_F64: f64 = f64::MIN;
463static MAX_F64: f64 = f64::MAX;
464static POSITIVE_INFINITY_F64: f64 = f64::INFINITY;
465static NEGATIVE_INFINITY_F64: f64 = f64::NEG_INFINITY;
466static NAN_F64: f64 = f64::NAN;
467static POSITIVE_ZERO_F64: f64 = 0.0f64;
468static NEGATIVE_ZERO_F64: f64 = -0.0f64;
469static EPSILON_F64: f64 = f64::EPSILON;
470
471unsafe impl Facet<'_> for f32 {
472 const SHAPE: &'static Shape = &const {
473 Shape::builder()
474 .id(ConstTypeId::of::<f32>())
475 .layout(Layout::new::<Self>())
476 .def(Def::Scalar(
477 ScalarDef::builder()
478 .affinity(
479 ScalarAffinity::number()
480 .float(1, 8, f32::MANTISSA_DIGITS as usize - 1, false)
481 .min(PtrConst::new(&raw const MIN_F32))
482 .max(PtrConst::new(&raw const MAX_F32))
483 .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F32))
484 .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F32))
485 .nan_sample(PtrConst::new(&raw const NAN_F32))
486 .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F32))
487 .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F32))
488 .epsilon(PtrConst::new(&raw const EPSILON_F32))
489 .build(),
490 )
491 .build(),
492 ))
493 .vtable(
494 &const {
495 let mut vtable = value_vtable_inner!(f32, |f, _opts| write!(f, "f32"));
496
497 vtable.try_from = Some(|source, source_shape, dest| {
498 if source_shape == Self::SHAPE {
499 return Ok(unsafe { dest.copy_from(source, source_shape) });
500 }
501 if source_shape == u64::SHAPE {
502 let value: u64 = *unsafe { source.get::<u64>() };
503 let converted: f32 = value as f32;
504 return Ok(unsafe { dest.put::<f32>(converted) });
505 }
506 if source_shape == i64::SHAPE {
507 let value: i64 = *unsafe { source.get::<i64>() };
508 let converted: f32 = value as f32;
509 return Ok(unsafe { dest.put::<f32>(converted) });
510 }
511 if source_shape == f64::SHAPE {
512 let value: f64 = *unsafe { source.get::<f64>() };
513 let converted: f32 = value as f32;
514 return Ok(unsafe { dest.put::<f32>(converted) });
515 }
516 Err(TryFromError::Incompatible)
517 });
518
519 vtable
520 },
521 )
522 .build()
523 };
524}
525
526unsafe impl Facet<'_> for f64 {
527 const SHAPE: &'static Shape = &const {
528 Shape::builder()
529 .id(ConstTypeId::of::<f64>())
530 .layout(Layout::new::<Self>())
531 .def(Def::Scalar(
532 ScalarDef::builder()
533 .affinity(
534 ScalarAffinity::number()
535 .float(1, 11, f64::MANTISSA_DIGITS as usize - 1, false)
536 .min(PtrConst::new(&raw const MIN_F64))
537 .max(PtrConst::new(&raw const MAX_F64))
538 .positive_infinity(PtrConst::new(&raw const POSITIVE_INFINITY_F64))
539 .negative_infinity(PtrConst::new(&raw const NEGATIVE_INFINITY_F64))
540 .nan_sample(PtrConst::new(&raw const NAN_F64))
541 .positive_zero(PtrConst::new(&raw const POSITIVE_ZERO_F64))
542 .negative_zero(PtrConst::new(&raw const NEGATIVE_ZERO_F64))
543 .epsilon(PtrConst::new(&raw const EPSILON_F64))
544 .build(),
545 )
546 .build(),
547 ))
548 .vtable(
549 &const {
550 let mut vtable = value_vtable_inner!(f64, |f, _opts| write!(f, "f64"));
551
552 vtable.try_from = Some(|source, source_shape, dest| {
553 if source_shape == Self::SHAPE {
554 return Ok(unsafe { dest.copy_from(source, source_shape) });
555 }
556 if source_shape == u64::SHAPE {
557 let value: u64 = *unsafe { source.get::<u64>() };
558 let converted: f64 = value as f64;
559 return Ok(unsafe { dest.put::<f64>(converted) });
560 }
561 if source_shape == i64::SHAPE {
562 let value: i64 = *unsafe { source.get::<i64>() };
563 let converted: f64 = value as f64;
564 return Ok(unsafe { dest.put::<f64>(converted) });
565 }
566 if source_shape == f32::SHAPE {
567 let value: f32 = *unsafe { source.get::<f32>() };
568 let converted: f64 = value as f64;
569 return Ok(unsafe { dest.put::<f64>(converted) });
570 }
571 Err(TryFromError::Incompatible)
572 });
573
574 vtable
575 },
576 )
577 .build()
578 };
579}
580
581unsafe impl Facet<'_> for core::net::SocketAddr {
582 const SHAPE: &'static Shape = &const {
583 Shape::builder()
584 .id(ConstTypeId::of::<Self>())
585 .layout(Layout::new::<Self>())
586 .def(Def::Scalar(
587 ScalarDef::builder()
588 .affinity(ScalarAffinity::socket_addr().build())
589 .build(),
590 ))
591 .vtable(value_vtable!(core::net::SocketAddr, |f, _opts| write!(
592 f,
593 "SocketAddr"
594 )))
595 .build()
596 };
597}
598
599unsafe impl Facet<'_> for core::net::IpAddr {
600 const SHAPE: &'static Shape = &const {
601 Shape::builder()
602 .id(ConstTypeId::of::<Self>())
603 .layout(Layout::new::<Self>())
604 .def(Def::Scalar(
605 ScalarDef::builder()
606 .affinity(ScalarAffinity::ip_addr().build())
607 .build(),
608 ))
609 .vtable(value_vtable!(core::net::IpAddr, |f, _opts| write!(
610 f,
611 "IpAddr"
612 )))
613 .build()
614 };
615}
616
617unsafe impl Facet<'_> for core::net::Ipv4Addr {
618 const SHAPE: &'static Shape = &const {
619 Shape::builder()
620 .id(ConstTypeId::of::<Self>())
621 .layout(Layout::new::<Self>())
622 .def(Def::Scalar(
623 ScalarDef::builder()
624 .affinity(ScalarAffinity::ip_addr().build())
625 .build(),
626 ))
627 .vtable(value_vtable!(core::net::Ipv4Addr, |f, _opts| write!(
628 f,
629 "Ipv4Addr"
630 )))
631 .build()
632 };
633}
634
635unsafe impl Facet<'_> for core::net::Ipv6Addr {
636 const SHAPE: &'static Shape = &const {
637 Shape::builder()
638 .id(ConstTypeId::of::<Self>())
639 .layout(Layout::new::<Self>())
640 .def(Def::Scalar(
641 ScalarDef::builder()
642 .affinity(ScalarAffinity::ip_addr().build())
643 .build(),
644 ))
645 .vtable(value_vtable!(core::net::Ipv6Addr, |f, _opts| write!(
646 f,
647 "Ipv6Addr"
648 )))
649 .build()
650 };
651}