serde_untagged/
int.rs

1use crate::error;
2use crate::UntaggedEnumVisitor;
3use serde::de::{Unexpected, Visitor};
4
5pub(crate) enum IntKind {
6    I8,
7    I16,
8    I32,
9    I64,
10    I128,
11    U8,
12    U16,
13    U32,
14    U64,
15    U128,
16}
17
18pub(crate) trait Integer:
19    Copy
20    + TryInto<i8>
21    + TryInto<i16>
22    + TryInto<i32>
23    + TryInto<i64>
24    + TryInto<i128>
25    + TryInto<u8>
26    + TryInto<u16>
27    + TryInto<u32>
28    + TryInto<u64>
29    + TryInto<u128>
30{
31}
32
33impl<T> Integer for T
34where
35    T: Copy,
36    i8: TryFrom<T>,
37    i16: TryFrom<T>,
38    i32: TryFrom<T>,
39    i64: TryFrom<T>,
40    i128: TryFrom<T>,
41    u8: TryFrom<T>,
42    u16: TryFrom<T>,
43    u32: TryFrom<T>,
44    u64: TryFrom<T>,
45    u128: TryFrom<T>,
46{
47}
48
49impl<'closure, 'de, Value> UntaggedEnumVisitor<'closure, 'de, Value> {
50    pub(crate) fn dispatch_integer<I, E>(
51        self,
52        value: I,
53        precedence: [IntKind; 10],
54    ) -> Result<Value, E>
55    where
56        I: Integer,
57        E: serde::de::Error,
58    {
59        for kind in precedence {
60            match kind {
61                IntKind::I8 => {
62                    if let Some(int) = i8::int_from(value) {
63                        if let Some(visit_i8) = self.visit_i8 {
64                            return visit_i8(int).map_err(error::unerase);
65                        }
66                    }
67                }
68                IntKind::I16 => {
69                    if let Some(int) = i16::int_from(value) {
70                        if let Some(visit_i16) = self.visit_i16 {
71                            return visit_i16(int).map_err(error::unerase);
72                        }
73                    }
74                }
75                IntKind::I32 => {
76                    if let Some(int) = i32::int_from(value) {
77                        if let Some(visit_i32) = self.visit_i32 {
78                            return visit_i32(int).map_err(error::unerase);
79                        }
80                    }
81                }
82                IntKind::I64 => {
83                    if let Some(int) = i64::int_from(value) {
84                        if let Some(visit_i64) = self.visit_i64 {
85                            return visit_i64(int).map_err(error::unerase);
86                        }
87                    }
88                }
89                IntKind::I128 => {
90                    if let Some(int) = i128::int_from(value) {
91                        if let Some(visit_i128) = self.visit_i128 {
92                            return visit_i128(int).map_err(error::unerase);
93                        }
94                    }
95                }
96                IntKind::U8 => {
97                    if let Some(int) = u8::int_from(value) {
98                        if let Some(visit_u8) = self.visit_u8 {
99                            return visit_u8(int).map_err(error::unerase);
100                        }
101                    }
102                }
103                IntKind::U16 => {
104                    if let Some(int) = u16::int_from(value) {
105                        if let Some(visit_u16) = self.visit_u16 {
106                            return visit_u16(int).map_err(error::unerase);
107                        }
108                    }
109                }
110                IntKind::U32 => {
111                    if let Some(int) = u32::int_from(value) {
112                        if let Some(visit_u32) = self.visit_u32 {
113                            return visit_u32(int).map_err(error::unerase);
114                        }
115                    }
116                }
117                IntKind::U64 => {
118                    if let Some(int) = u64::int_from(value) {
119                        if let Some(visit_u64) = self.visit_u64 {
120                            return visit_u64(int).map_err(error::unerase);
121                        }
122                    }
123                }
124                IntKind::U128 => {
125                    if let Some(int) = u128::int_from(value) {
126                        if let Some(visit_u128) = self.visit_u128 {
127                            return visit_u128(int).map_err(error::unerase);
128                        }
129                    }
130                }
131            }
132        }
133        if let Some(int) = u64::int_from(value) {
134            return Err(E::invalid_type(Unexpected::Unsigned(int), &self));
135        }
136        if let Some(int) = i64::int_from(value) {
137            return Err(E::invalid_type(Unexpected::Signed(int), &self));
138        }
139        if let Some(int) = u128::int_from(value) {
140            return crate::DefaultVisitor::new(&self).visit_u128(int);
141        }
142        if let Some(int) = i128::int_from(value) {
143            return crate::DefaultVisitor::new(&self).visit_i128(int);
144        }
145        unreachable!()
146    }
147}
148
149trait IntFrom<I>: Sized {
150    fn int_from(int: I) -> Option<Self>;
151}
152
153impl<T, I> IntFrom<I> for T
154where
155    I: TryInto<Self>,
156{
157    fn int_from(int: I) -> Option<Self> {
158        int.try_into().ok()
159    }
160}