facet_reflect/wip/
put_f64.rs

1use crate::{ReflectError, Wip};
2use core::num::{
3    NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize, NonZeroU8, NonZeroU16, NonZeroU32,
4    NonZeroU64, NonZeroUsize,
5};
6use facet_core::{Def, ScalarAffinity};
7
8impl Wip<'_> {
9    /// Returns true if the current frame can accept a f64 into a supported numeric type.
10    pub fn can_put_f64(&self) -> bool {
11        let shape = self.shape();
12        match shape.def {
13            Def::Scalar(sd) => matches!(sd.affinity, ScalarAffinity::Number(_)),
14            _ => false,
15        }
16    }
17
18    /// Attempts to put a `f64` into the current frame, converting to the underlying numeric type.
19    pub fn try_put_f64(self, number: f64) -> Result<Self, ReflectError> {
20        let shape = self.shape();
21        // Ensure this is a numeric scalar
22        match shape.def {
23            Def::Scalar(sd) => match sd.affinity {
24                ScalarAffinity::Number(_) => {}
25                ScalarAffinity::String(_) => {
26                    return Err(ReflectError::OperationFailed {
27                        shape,
28                        operation: "cannot parse number into string scalar",
29                    });
30                }
31                _ => {
32                    return Err(ReflectError::OperationFailed {
33                        shape,
34                        operation: "tried to put f64 into non-number scalar",
35                    });
36                }
37            },
38            _ => {
39                return Err(ReflectError::OperationFailed {
40                    shape,
41                    operation: "tried to put f64 into non-scalar type",
42                });
43            }
44        }
45
46        // Match on the concrete Rust type
47        if shape.is_type::<u8>() {
48            if (0.0..=u8::MAX as f64).contains(&number) {
49                self.put(number as u8)
50            } else {
51                Err(ReflectError::OperationFailed {
52                    shape,
53                    operation: "number out of range",
54                })
55            }
56        } else if shape.is_type::<u16>() {
57            if (0.0..=u16::MAX as f64).contains(&number) {
58                self.put(number as u16)
59            } else {
60                Err(ReflectError::OperationFailed {
61                    shape,
62                    operation: "number out of range",
63                })
64            }
65        } else if shape.is_type::<u32>() {
66            if (0.0..=u32::MAX as f64).contains(&number) {
67                self.put(number as u32)
68            } else {
69                Err(ReflectError::OperationFailed {
70                    shape,
71                    operation: "number out of range",
72                })
73            }
74        } else if shape.is_type::<u64>() {
75            if (0.0..=u64::MAX as f64).contains(&number) {
76                self.put(number as u64)
77            } else {
78                Err(ReflectError::OperationFailed {
79                    shape,
80                    operation: "number out of range",
81                })
82            }
83        } else if shape.is_type::<usize>() {
84            if (0.0..=usize::MAX as f64).contains(&number) {
85                self.put(number as usize)
86            } else {
87                Err(ReflectError::OperationFailed {
88                    shape,
89                    operation: "number out of range",
90                })
91            }
92        } else if shape.is_type::<i8>() {
93            if (i8::MIN as f64..=i8::MAX as f64).contains(&number) {
94                self.put(number as i8)
95            } else {
96                Err(ReflectError::OperationFailed {
97                    shape,
98                    operation: "number out of range",
99                })
100            }
101        } else if shape.is_type::<i16>() {
102            if (i16::MIN as f64..=i16::MAX as f64).contains(&number) {
103                self.put(number as i16)
104            } else {
105                Err(ReflectError::OperationFailed {
106                    shape,
107                    operation: "number out of range",
108                })
109            }
110        } else if shape.is_type::<i32>() {
111            if (i32::MIN as f64..=i32::MAX as f64).contains(&number) {
112                self.put(number as i32)
113            } else {
114                Err(ReflectError::OperationFailed {
115                    shape,
116                    operation: "number out of range",
117                })
118            }
119        } else if shape.is_type::<i64>() {
120            if (i64::MIN as f64..=i64::MAX as f64).contains(&number) {
121                self.put(number as i64)
122            } else {
123                Err(ReflectError::OperationFailed {
124                    shape,
125                    operation: "number out of range",
126                })
127            }
128        } else if shape.is_type::<isize>() {
129            if (isize::MIN as f64..=isize::MAX as f64).contains(&number) {
130                self.put(number as isize)
131            } else {
132                Err(ReflectError::OperationFailed {
133                    shape,
134                    operation: "number out of range",
135                })
136            }
137        } else if shape.is_type::<f32>() {
138            if (f32::MIN as f64..=f32::MAX as f64).contains(&number) {
139                self.put(number as f32)
140            } else {
141                Err(ReflectError::OperationFailed {
142                    shape,
143                    operation: "number out of range",
144                })
145            }
146        } else if shape.is_type::<f64>() {
147            self.put(number)
148        } else if shape.is_type::<NonZeroU8>() {
149            if (1.0..=u8::MAX as f64).contains(&number) {
150                let value = NonZeroU8::new(number as u8).unwrap();
151                self.put(value)
152            } else {
153                Err(ReflectError::OperationFailed {
154                    shape,
155                    operation: "number out of range",
156                })
157            }
158        } else if shape.is_type::<NonZeroU16>() {
159            if (1.0..=u16::MAX as f64).contains(&number) {
160                let value = NonZeroU16::new(number as u16).unwrap();
161                self.put(value)
162            } else {
163                Err(ReflectError::OperationFailed {
164                    shape,
165                    operation: "number out of range",
166                })
167            }
168        } else if shape.is_type::<NonZeroU32>() {
169            if (1.0..=u32::MAX as f64).contains(&number) {
170                let value = NonZeroU32::new(number as u32).unwrap();
171                self.put(value)
172            } else {
173                Err(ReflectError::OperationFailed {
174                    shape,
175                    operation: "number out of range",
176                })
177            }
178        } else if shape.is_type::<NonZeroU64>() {
179            if (1.0..=u64::MAX as f64).contains(&number) {
180                let value = NonZeroU64::new(number as u64).unwrap();
181                self.put(value)
182            } else {
183                Err(ReflectError::OperationFailed {
184                    shape,
185                    operation: "number out of range",
186                })
187            }
188        } else if shape.is_type::<NonZeroUsize>() {
189            if (1.0..=usize::MAX as f64).contains(&number) {
190                let value = NonZeroUsize::new(number as usize).unwrap();
191                self.put(value)
192            } else {
193                Err(ReflectError::OperationFailed {
194                    shape,
195                    operation: "number out of range",
196                })
197            }
198        } else if shape.is_type::<NonZeroI8>() {
199            if (1.0..=i8::MAX as f64).contains(&number) {
200                let value = NonZeroI8::new(number as i8).unwrap();
201                self.put(value)
202            } else {
203                Err(ReflectError::OperationFailed {
204                    shape,
205                    operation: "number out of range",
206                })
207            }
208        } else if shape.is_type::<NonZeroI16>() {
209            if (1.0..=i16::MAX as f64).contains(&number) {
210                let value = NonZeroI16::new(number as i16).unwrap();
211                self.put(value)
212            } else {
213                Err(ReflectError::OperationFailed {
214                    shape,
215                    operation: "number out of range",
216                })
217            }
218        } else if shape.is_type::<NonZeroI32>() {
219            if (1.0..=i32::MAX as f64).contains(&number) {
220                let value = NonZeroI32::new(number as i32).unwrap();
221                self.put(value)
222            } else {
223                Err(ReflectError::OperationFailed {
224                    shape,
225                    operation: "number out of range",
226                })
227            }
228        } else if shape.is_type::<NonZeroI64>() {
229            if (1.0..=i64::MAX as f64).contains(&number) {
230                let value = NonZeroI64::new(number as i64).unwrap();
231                self.put(value)
232            } else {
233                Err(ReflectError::OperationFailed {
234                    shape,
235                    operation: "number out of range",
236                })
237            }
238        } else if shape.is_type::<NonZeroIsize>() {
239            if (1.0..=isize::MAX as f64).contains(&number) {
240                let value = NonZeroIsize::new(number as isize).unwrap();
241                self.put(value)
242            } else {
243                Err(ReflectError::OperationFailed {
244                    shape,
245                    operation: "number out of range",
246                })
247            }
248        } else {
249            Err(ReflectError::OperationFailed {
250                shape,
251                operation: "number type not supported by try_put_f64",
252            })
253        }
254    }
255}