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 .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
371static 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
380static 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}