facet_reflect/
scalar.rs

1use core::any::TypeId;
2use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
3
4use facet_core::{ConstTypeId, Shape};
5
6/// All scalar types supported out of the box by peek and poke.
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
8pub enum ScalarType {
9    /// Unit tuple `()`.
10    Unit,
11    /// Primitive type `bool`.
12    Bool,
13    /// Primitive type `char`.
14    Char,
15    /// Primitive type `str`.
16    Str,
17    /// `alloc::string::String`.
18    String,
19    /// `alloc::borrow::Cow<'_, str>`.
20    CowStr,
21    /// Primitive type `f32`.
22    F32,
23    /// Primitive type `f64`.
24    F64,
25    /// Primitive type `u8`.
26    U8,
27    /// Primitive type `u16`.
28    U16,
29    /// Primitive type `u32`.
30    U32,
31    /// Primitive type `u64`.
32    U64,
33    /// Primitive type `u128`.
34    U128,
35    /// Primitive type `usize`.
36    USize,
37    /// Primitive type `i8`.
38    I8,
39    /// Primitive type `i16`.
40    I16,
41    /// Primitive type `i32`.
42    I32,
43    /// Primitive type `i64`.
44    I64,
45    /// Primitive type `i128`.
46    I128,
47    /// Primitive type `isize`.
48    ISize,
49    /// `core::net::SocketAddr`.
50    SocketAddr,
51    /// `core::net::IpAddr`.
52    IpAddr,
53    /// `core::net::Ipv4Addr`.
54    Ipv4Addr,
55    /// `core::net::Ipv6Addr`.
56    Ipv6Addr,
57    /// `facet_core::typeid::ConstTypeId`.
58    ConstTypeId,
59}
60
61impl ScalarType {
62    /// Infer the type from a shape definition.
63    #[inline]
64    pub fn try_from_shape(shape: &Shape<'_>) -> Option<Self> {
65        let type_id = shape.id.get();
66
67        #[cfg(feature = "alloc")]
68        if type_id == TypeId::of::<alloc::string::String>() {
69            return Some(ScalarType::String);
70        } else if type_id == TypeId::of::<alloc::borrow::Cow<'_, str>>() {
71            return Some(ScalarType::CowStr);
72        } else if type_id == TypeId::of::<str>() {
73            return Some(ScalarType::Str);
74        } else if type_id == TypeId::of::<core::net::SocketAddr>() {
75            return Some(ScalarType::SocketAddr);
76        }
77
78        if type_id == TypeId::of::<()>() {
79            Some(Self::Unit)
80        } else if type_id == TypeId::of::<bool>() {
81            Some(ScalarType::Bool)
82        } else if type_id == TypeId::of::<char>() {
83            Some(ScalarType::Char)
84        } else if type_id == TypeId::of::<&str>() {
85            Some(ScalarType::Str)
86        } else if type_id == TypeId::of::<f32>() {
87            Some(ScalarType::F32)
88        } else if type_id == TypeId::of::<f64>() {
89            Some(ScalarType::F64)
90        } else if type_id == TypeId::of::<u8>() {
91            Some(ScalarType::U8)
92        } else if type_id == TypeId::of::<u16>() {
93            Some(ScalarType::U16)
94        } else if type_id == TypeId::of::<u32>() {
95            Some(ScalarType::U32)
96        } else if type_id == TypeId::of::<u64>() {
97            Some(ScalarType::U64)
98        } else if type_id == TypeId::of::<u128>() {
99            Some(ScalarType::U128)
100        } else if type_id == TypeId::of::<usize>() {
101            Some(ScalarType::USize)
102        } else if type_id == TypeId::of::<i8>() {
103            Some(ScalarType::I8)
104        } else if type_id == TypeId::of::<i16>() {
105            Some(ScalarType::I16)
106        } else if type_id == TypeId::of::<i32>() {
107            Some(ScalarType::I32)
108        } else if type_id == TypeId::of::<i64>() {
109            Some(ScalarType::I64)
110        } else if type_id == TypeId::of::<i128>() {
111            Some(ScalarType::I128)
112        } else if type_id == TypeId::of::<isize>() {
113            Some(ScalarType::ISize)
114        } else if type_id == TypeId::of::<IpAddr>() {
115            Some(ScalarType::IpAddr)
116        } else if type_id == TypeId::of::<Ipv4Addr>() {
117            Some(ScalarType::Ipv4Addr)
118        } else if type_id == TypeId::of::<Ipv6Addr>() {
119            Some(ScalarType::Ipv6Addr)
120        } else if type_id == TypeId::of::<ConstTypeId>() {
121            Some(ScalarType::ConstTypeId)
122        } else {
123            None
124        }
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
133
134    use facet_core::Facet;
135
136    /// Simple check to ensure every can be loaded from a shape.
137    #[test]
138    fn test_ensure_try_from_shape() {
139        assert_eq!(
140            ScalarType::Unit,
141            ScalarType::try_from_shape(<()>::SHAPE).unwrap()
142        );
143        assert_eq!(
144            ScalarType::Bool,
145            ScalarType::try_from_shape(bool::SHAPE).unwrap()
146        );
147        assert_eq!(
148            ScalarType::Str,
149            ScalarType::try_from_shape(<&str>::SHAPE).unwrap()
150        );
151        #[cfg(feature = "std")]
152        assert_eq!(
153            ScalarType::String,
154            ScalarType::try_from_shape(String::SHAPE).unwrap()
155        );
156        #[cfg(feature = "std")]
157        assert_eq!(
158            ScalarType::CowStr,
159            ScalarType::try_from_shape(alloc::borrow::Cow::SHAPE).unwrap()
160        );
161        assert_eq!(
162            ScalarType::F32,
163            ScalarType::try_from_shape(f32::SHAPE).unwrap()
164        );
165        assert_eq!(
166            ScalarType::F64,
167            ScalarType::try_from_shape(f64::SHAPE).unwrap()
168        );
169        assert_eq!(
170            ScalarType::U8,
171            ScalarType::try_from_shape(u8::SHAPE).unwrap()
172        );
173        assert_eq!(
174            ScalarType::U16,
175            ScalarType::try_from_shape(u16::SHAPE).unwrap()
176        );
177        assert_eq!(
178            ScalarType::U32,
179            ScalarType::try_from_shape(u32::SHAPE).unwrap()
180        );
181        assert_eq!(
182            ScalarType::U64,
183            ScalarType::try_from_shape(u64::SHAPE).unwrap()
184        );
185        assert_eq!(
186            ScalarType::U128,
187            ScalarType::try_from_shape(u128::SHAPE).unwrap()
188        );
189        assert_eq!(
190            ScalarType::USize,
191            ScalarType::try_from_shape(usize::SHAPE).unwrap()
192        );
193        assert_eq!(
194            ScalarType::I8,
195            ScalarType::try_from_shape(i8::SHAPE).unwrap()
196        );
197        assert_eq!(
198            ScalarType::I16,
199            ScalarType::try_from_shape(i16::SHAPE).unwrap()
200        );
201        assert_eq!(
202            ScalarType::I32,
203            ScalarType::try_from_shape(i32::SHAPE).unwrap()
204        );
205        assert_eq!(
206            ScalarType::I64,
207            ScalarType::try_from_shape(i64::SHAPE).unwrap()
208        );
209        assert_eq!(
210            ScalarType::I128,
211            ScalarType::try_from_shape(i128::SHAPE).unwrap()
212        );
213        assert_eq!(
214            ScalarType::ISize,
215            ScalarType::try_from_shape(isize::SHAPE).unwrap()
216        );
217        #[cfg(feature = "std")]
218        assert_eq!(
219            ScalarType::SocketAddr,
220            ScalarType::try_from_shape(core::net::SocketAddr::SHAPE).unwrap()
221        );
222        assert_eq!(
223            ScalarType::IpAddr,
224            ScalarType::try_from_shape(IpAddr::SHAPE).unwrap()
225        );
226        assert_eq!(
227            ScalarType::Ipv4Addr,
228            ScalarType::try_from_shape(Ipv4Addr::SHAPE).unwrap()
229        );
230        assert_eq!(
231            ScalarType::Ipv6Addr,
232            ScalarType::try_from_shape(Ipv6Addr::SHAPE).unwrap()
233        );
234        assert_eq!(
235            ScalarType::ConstTypeId,
236            ScalarType::try_from_shape(ConstTypeId::SHAPE).unwrap()
237        );
238    }
239}