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