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