core_json_traits/
float.rs1use core::num::FpCategory;
2use crate::{Read, Stack, JsonError, Value, JsonDeserialize, JsonSerialize};
3
4impl JsonDeserialize for f64 {
5 fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
6 value: Value<'read, 'parent, B, S>,
7 ) -> Result<Self, JsonError<'read, B, S>> {
8 value.to_number()?.f64().ok_or(JsonError::TypeError)
9 }
10}
11
12#[derive(Clone, Copy, Default, Debug)]
18pub struct JsonF64(f64);
19
20impl TryFrom<f64> for JsonF64 {
21 type Error = FpCategory;
22 fn try_from(value: f64) -> Result<Self, Self::Error> {
23 let class = value.classify();
24 match class {
25 FpCategory::Nan | FpCategory::Infinite => Err(class)?,
26 FpCategory::Zero | FpCategory::Normal | FpCategory::Subnormal => {}
27 }
28 Ok(Self(value))
29 }
30}
31
32impl From<JsonF64> for f64 {
33 fn from(value: JsonF64) -> f64 {
34 value.0
35 }
36}
37
38impl JsonDeserialize for JsonF64 {
39 fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
40 value: Value<'read, 'parent, B, S>,
41 ) -> Result<Self, JsonError<'read, B, S>> {
42 JsonF64::try_from(f64::deserialize(value)?).map_err(|_| JsonError::TypeError)
43 }
44}
45
46#[cfg(not(feature = "ryu"))]
47mod serialize {
48 use core::fmt::Write;
49 use crate::NumberSink;
50 use super::*;
51
52 impl JsonSerialize for JsonF64 {
53 fn serialize(&self) -> impl Iterator<Item = char> {
55 let mut sink = NumberSink::new();
56 write!(&mut sink, "{}", self.0).expect("infallible `NumberSink` raised an error");
57 let (buf, len) = sink.imprecise_str().expect("`NumberSink` couldn't sink a `f64` from Rust");
58 buf.into_iter().take(len).map(|b| b as char)
60 }
61 }
62}
63
64#[cfg(feature = "ryu")]
65mod serialize {
66 use super::*;
67
68 impl JsonSerialize for JsonF64 {
69 fn serialize(&self) -> impl Iterator<Item = char> {
70 let mut buffer = ryu::Buffer::new();
71 let result = buffer.format_finite(self.0).as_bytes();
73 let mut owned = [0; core::mem::size_of::<ryu::Buffer>()];
79 owned[.. result.len()].copy_from_slice(result);
80 owned.into_iter().take(result.len()).map(|byte| byte as char)
82 }
83 }
84}