intaglio/
convert.rs

1use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
2
3use crate::{Symbol, SymbolOverflowError};
4
5impl From<u8> for Symbol {
6    #[inline]
7    fn from(id: u8) -> Self {
8        Self(id.into())
9    }
10}
11
12impl From<NonZeroU8> for Symbol {
13    #[inline]
14    fn from(sym: NonZeroU8) -> Self {
15        Self(sym.get().into())
16    }
17}
18
19impl From<u16> for Symbol {
20    #[inline]
21    fn from(id: u16) -> Self {
22        Self(id.into())
23    }
24}
25
26impl From<NonZeroU16> for Symbol {
27    #[inline]
28    fn from(sym: NonZeroU16) -> Self {
29        Self(sym.get().into())
30    }
31}
32
33impl From<u32> for Symbol {
34    #[inline]
35    fn from(id: u32) -> Self {
36        Self(id)
37    }
38}
39
40impl From<NonZeroU32> for Symbol {
41    #[inline]
42    fn from(sym: NonZeroU32) -> Self {
43        Self(sym.get())
44    }
45}
46
47impl TryFrom<u64> for Symbol {
48    type Error = SymbolOverflowError;
49
50    #[inline]
51    fn try_from(value: u64) -> Result<Self, Self::Error> {
52        let id = u32::try_from(value)?;
53        Ok(id.into())
54    }
55}
56
57impl TryFrom<NonZeroU64> for Symbol {
58    type Error = SymbolOverflowError;
59
60    #[inline]
61    fn try_from(value: NonZeroU64) -> Result<Self, Self::Error> {
62        let id = u32::try_from(value.get())?;
63        Ok(id.into())
64    }
65}
66
67impl TryFrom<usize> for Symbol {
68    type Error = SymbolOverflowError;
69
70    #[inline]
71    fn try_from(value: usize) -> Result<Self, Self::Error> {
72        let id = u32::try_from(value)?;
73        Ok(id.into())
74    }
75}
76
77impl TryFrom<NonZeroUsize> for Symbol {
78    type Error = SymbolOverflowError;
79
80    #[inline]
81    fn try_from(value: NonZeroUsize) -> Result<Self, Self::Error> {
82        let id = u32::try_from(value.get())?;
83        Ok(id.into())
84    }
85}
86
87impl From<&u8> for Symbol {
88    #[inline]
89    fn from(id: &u8) -> Self {
90        Self((*id).into())
91    }
92}
93
94impl From<&NonZeroU8> for Symbol {
95    #[inline]
96    fn from(sym: &NonZeroU8) -> Self {
97        Self(sym.get().into())
98    }
99}
100
101impl From<&u16> for Symbol {
102    #[inline]
103    fn from(id: &u16) -> Self {
104        Self((*id).into())
105    }
106}
107
108impl From<&NonZeroU16> for Symbol {
109    #[inline]
110    fn from(sym: &NonZeroU16) -> Self {
111        Self(sym.get().into())
112    }
113}
114
115impl From<&u32> for Symbol {
116    #[inline]
117    fn from(id: &u32) -> Self {
118        Self(*id)
119    }
120}
121
122impl From<&NonZeroU32> for Symbol {
123    #[inline]
124    fn from(sym: &NonZeroU32) -> Self {
125        Self(sym.get())
126    }
127}
128
129impl TryFrom<&u64> for Symbol {
130    type Error = SymbolOverflowError;
131
132    #[inline]
133    fn try_from(value: &u64) -> Result<Self, Self::Error> {
134        let id = u32::try_from(*value)?;
135        Ok(id.into())
136    }
137}
138
139impl TryFrom<&NonZeroU64> for Symbol {
140    type Error = SymbolOverflowError;
141
142    #[inline]
143    fn try_from(value: &NonZeroU64) -> Result<Self, Self::Error> {
144        let id = u32::try_from(value.get())?;
145        Ok(id.into())
146    }
147}
148
149impl TryFrom<&usize> for Symbol {
150    type Error = SymbolOverflowError;
151
152    #[inline]
153    fn try_from(value: &usize) -> Result<Self, Self::Error> {
154        let id = u32::try_from(*value)?;
155        Ok(id.into())
156    }
157}
158
159impl TryFrom<&NonZeroUsize> for Symbol {
160    type Error = SymbolOverflowError;
161
162    #[inline]
163    fn try_from(value: &NonZeroUsize) -> Result<Self, Self::Error> {
164        let id = u32::try_from(value.get())?;
165        Ok(id.into())
166    }
167}
168
169impl From<Symbol> for u32 {
170    #[inline]
171    fn from(sym: Symbol) -> Self {
172        sym.id()
173    }
174}
175
176impl From<Symbol> for u64 {
177    #[inline]
178    fn from(sym: Symbol) -> Self {
179        sym.id().into()
180    }
181}
182
183impl From<Symbol> for usize {
184    #[inline]
185    fn from(sym: Symbol) -> Self {
186        // Ensure this cast is lossless.
187        const_assert!(usize::BITS >= u32::BITS);
188
189        sym.id() as usize
190    }
191}
192
193impl From<Symbol> for i64 {
194    #[inline]
195    fn from(sym: Symbol) -> Self {
196        sym.id().into()
197    }
198}
199
200impl From<&Symbol> for u32 {
201    #[inline]
202    fn from(sym: &Symbol) -> Self {
203        sym.id()
204    }
205}
206
207impl From<&Symbol> for u64 {
208    #[inline]
209    fn from(sym: &Symbol) -> Self {
210        sym.id().into()
211    }
212}
213
214impl From<&Symbol> for usize {
215    #[inline]
216    fn from(sym: &Symbol) -> Self {
217        (*sym).into()
218    }
219}
220
221impl From<&Symbol> for i64 {
222    #[inline]
223    fn from(sym: &Symbol) -> Self {
224        sym.id().into()
225    }
226}
227
228#[cfg(test)]
229mod tests {
230    use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
231
232    use crate::Symbol;
233
234    #[test]
235    fn symbol_from_primitive() {
236        assert_eq!(Symbol::from(0_u8), Symbol::new(0));
237        assert_eq!(Symbol::from(17_u8), Symbol::new(17));
238
239        assert_eq!(Symbol::from(0_u16), Symbol::new(0));
240        assert_eq!(Symbol::from(17_u16), Symbol::new(17));
241
242        assert_eq!(Symbol::from(0_u32), Symbol::new(0));
243        assert_eq!(Symbol::from(17_u32), Symbol::new(17));
244
245        assert_eq!(Symbol::try_from(0_u64).unwrap(), Symbol::new(0));
246        assert_eq!(Symbol::try_from(17_u64).unwrap(), Symbol::new(17));
247
248        Symbol::try_from(u64::MAX).unwrap_err();
249        Symbol::try_from(u64::from(u32::MAX) + 1).unwrap_err();
250
251        assert_eq!(Symbol::try_from(0_usize).unwrap(), Symbol::new(0));
252        assert_eq!(Symbol::try_from(17_usize).unwrap(), Symbol::new(17));
253
254        #[cfg(target_pointer_width = "64")]
255        {
256            Symbol::try_from(usize::MAX).unwrap_err();
257            Symbol::try_from(u64::from(u32::MAX) + 1).unwrap_err();
258        }
259    }
260
261    #[test]
262    fn symbol_from_primitive_ref() {
263        assert_eq!(Symbol::from(&0_u8), Symbol::new(0));
264        assert_eq!(Symbol::from(&17_u8), Symbol::new(17));
265
266        assert_eq!(Symbol::from(&0_u16), Symbol::new(0));
267        assert_eq!(Symbol::from(&17_u16), Symbol::new(17));
268
269        assert_eq!(Symbol::from(&0_u32), Symbol::new(0));
270        assert_eq!(Symbol::from(&17_u32), Symbol::new(17));
271
272        assert_eq!(Symbol::try_from(&0_u64).unwrap(), Symbol::new(0));
273        assert_eq!(Symbol::try_from(&17_u64).unwrap(), Symbol::new(17));
274
275        Symbol::try_from(&u64::MAX).unwrap_err();
276        Symbol::try_from(&(u64::from(u32::MAX) + 1)).unwrap_err();
277
278        assert_eq!(Symbol::try_from(&0_usize).unwrap(), Symbol::new(0));
279        assert_eq!(Symbol::try_from(&17_usize).unwrap(), Symbol::new(17));
280
281        #[cfg(target_pointer_width = "64")]
282        {
283            Symbol::try_from(&usize::MAX).unwrap_err();
284            Symbol::try_from(&(u64::from(u32::MAX) + 1)).unwrap_err();
285        }
286    }
287
288    #[test]
289    fn symbol_from_nonzero() {
290        assert_eq!(
291            Symbol::from(NonZeroU8::new(17_u8).unwrap()),
292            Symbol::new(17)
293        );
294
295        assert_eq!(
296            Symbol::from(NonZeroU16::new(17_u16).unwrap()),
297            Symbol::new(17)
298        );
299
300        assert_eq!(
301            Symbol::from(NonZeroU32::new(17_u32).unwrap()),
302            Symbol::new(17)
303        );
304
305        assert_eq!(
306            Symbol::try_from(NonZeroU64::new(17_u64).unwrap()).unwrap(),
307            Symbol::new(17)
308        );
309
310        Symbol::try_from(NonZeroU64::new(u64::MAX).unwrap()).unwrap_err();
311        Symbol::try_from(NonZeroU64::new(u64::from(u32::MAX) + 1).unwrap()).unwrap_err();
312
313        assert_eq!(
314            Symbol::try_from(NonZeroUsize::new(17_usize).unwrap()).unwrap(),
315            Symbol::new(17)
316        );
317
318        #[cfg(target_pointer_width = "64")]
319        {
320            Symbol::try_from(NonZeroUsize::new(usize::MAX).unwrap()).unwrap_err();
321            Symbol::try_from(NonZeroUsize::new((usize::try_from(u32::MAX).unwrap()) + 1).unwrap())
322                .unwrap_err();
323        }
324    }
325
326    #[test]
327    fn symbol_from_nonzero_ref() {
328        assert_eq!(
329            Symbol::from(&NonZeroU8::new(17_u8).unwrap()),
330            Symbol::new(17)
331        );
332
333        assert_eq!(
334            Symbol::from(&NonZeroU16::new(17_u16).unwrap()),
335            Symbol::new(17)
336        );
337
338        assert_eq!(
339            Symbol::from(&NonZeroU32::new(17_u32).unwrap()),
340            Symbol::new(17)
341        );
342
343        assert_eq!(
344            Symbol::try_from(&NonZeroU64::new(17_u64).unwrap()).unwrap(),
345            Symbol::new(17)
346        );
347
348        Symbol::try_from(&NonZeroU64::new(u64::MAX).unwrap()).unwrap_err();
349        Symbol::try_from(&NonZeroU64::new(u64::from(u32::MAX) + 1).unwrap()).unwrap_err();
350
351        assert_eq!(
352            Symbol::try_from(&NonZeroUsize::new(17_usize).unwrap()).unwrap(),
353            Symbol::new(17)
354        );
355
356        #[cfg(target_pointer_width = "64")]
357        {
358            Symbol::try_from(&NonZeroUsize::new(usize::MAX).unwrap()).unwrap_err();
359            Symbol::try_from(&NonZeroUsize::new((usize::try_from(u32::MAX).unwrap()) + 1).unwrap())
360                .unwrap_err();
361        }
362    }
363
364    #[test]
365    fn symbol_into_u32_eql_symbol_as_id() {
366        let test_cases = [0, 1, 17, 192, u32::MAX];
367        for id in test_cases {
368            let sym = Symbol::new(id);
369            assert_eq!(u32::from(sym), id);
370            assert_eq!(u32::from(&sym), id);
371            assert_eq!(u32::from(sym), sym.id());
372            assert_eq!(u32::from(&sym), sym.id());
373        }
374    }
375
376    #[test]
377    fn primitive_from_symbol() {
378        assert_eq!(0_u32, u32::from(Symbol::new(0)));
379        assert_eq!(17_u32, u32::from(Symbol::new(17)));
380
381        assert_eq!(0_u64, u64::from(Symbol::new(0)));
382        assert_eq!(17_u64, u64::from(Symbol::new(17)));
383
384        assert_eq!(0_usize, usize::from(Symbol::new(0)));
385        assert_eq!(17_usize, usize::from(Symbol::new(17)));
386
387        assert_eq!(0_i64, i64::from(Symbol::new(0)));
388        assert_eq!(17_i64, i64::from(Symbol::new(17)));
389    }
390
391    #[test]
392    fn primitive_from_symbol_ref() {
393        assert_eq!(0_u32, u32::from(&Symbol::new(0)));
394        assert_eq!(17_u32, u32::from(&Symbol::new(17)));
395
396        assert_eq!(0_u64, u64::from(&Symbol::new(0)));
397        assert_eq!(17_u64, u64::from(&Symbol::new(17)));
398
399        assert_eq!(0_usize, usize::from(&Symbol::new(0)));
400        assert_eq!(17_usize, usize::from(&Symbol::new(17)));
401
402        assert_eq!(0_i64, i64::from(&Symbol::new(0)));
403        assert_eq!(17_i64, i64::from(&Symbol::new(17)));
404    }
405}