value_bag/internal/cast/
primitive.rs1#[cfg(feature = "alloc")]
7use crate::std::string::String;
8
9use crate::ValueBag;
10
11use crate::std::any::TypeId;
17
18enum Void {}
19
20#[repr(transparent)]
21struct VoidRef<'a>(*const &'a Void);
22
23macro_rules! check_type_ids {
24 (&$l:lifetime $v:ident => $(
25 $(#[cfg($($cfg:tt)*)])*
26 $ty:ty,
27 )*
28 ) => {
29 $(
30 $(#[cfg($($cfg)*)])*
31 if TypeId::of::<T>() == TypeId::of::<$ty>() {
32 let v = unsafe { *($v.0 as *const & $l $ty) };
34
35 return Some(ValueBag::from(v));
36 }
37 )*
38 $(
39 $(#[cfg($($cfg)*)])*
40 if TypeId::of::<T>() == TypeId::of::<Option<$ty>>() {
41 let v = unsafe { *($v.0 as *const & $l Option<$ty>) };
43
44 if let Some(v) = v {
45 return Some(ValueBag::from(v));
46 } else {
47 return Some(ValueBag::empty());
48 }
49 }
50 )*
51 };
52}
53
54pub(in crate::internal) fn from_any<'v, T: ?Sized + 'static>(value: &'v T) -> Option<ValueBag<'v>> {
55 let type_ids = |v: VoidRef<'v>| {
56 if TypeId::of::<T>() == TypeId::of::<str>() {
57 let v = unsafe { *(v.0 as *const &'v str) };
59
60 return Some(ValueBag::from(v));
61 }
62
63 check_type_ids!(
64 &'v v =>
65 usize,
66 u8,
67 u16,
68 u32,
69 u64,
70 u128,
71 isize,
72 i8,
73 i16,
74 i32,
75 i64,
76 i128,
77 f32,
78 f64,
79 char,
80 bool,
81 &'static str,
82 #[cfg(feature = "alloc")]
85 String,
86 );
87
88 None
89 };
90
91 (type_ids)(VoidRef(&(value) as *const &'v T as *const &'v Void))
92}
93
94#[cfg(feature = "owned")]
95pub(in crate::internal) fn from_owned_any<'a, T: ?Sized + 'static>(
96 value: &'a T,
97) -> Option<ValueBag<'static>> {
98 let type_ids = |v: VoidRef<'a>| {
99 check_type_ids!(
100 &'a v =>
101 usize,
102 u8,
103 u16,
104 u32,
105 u64,
106 #[cfg(feature = "inline-i128")]
107 u128,
108 isize,
109 i8,
110 i16,
111 i32,
112 i64,
113 #[cfg(feature = "inline-i128")]
114 i128,
115 f32,
116 f64,
117 char,
118 bool,
119 );
120
121 None
122 };
123
124 (type_ids)(VoidRef(&(value) as *const &'a T as *const &'a Void))
125}