facet_reflect/
scalar.rs

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