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 .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
387static 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
396static 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}