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 .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
402static 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
411static 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}