json_streaming/shared/
float_format.rs

1
2/// This trait allows customization of how json-streaming formats floating point numbers.
3///
4/// There are many valid string representations of a given number. The number `10.0` can e.g.
5///  be represented as `10.0`, `10`, `1e2`, `1.0e2`, or `1.0e+2` and many others. There is no
6///  technical reason to customize this, it is entirely about human readability.
7///
8/// See the 'float_format' example for details.
9pub trait FloatFormat {
10    fn write_f64(f: &mut impl core::fmt::Write, value: f64) -> core::fmt::Result;
11    fn write_f32(f: &mut impl core::fmt::Write, value: f32) -> core::fmt::Result;
12}
13
14/// This is the default formatter for floating point numbers. It writes numbers from 1e-3 to
15///  1e6 as regular decimal numbers, and numbers outside that range in exponential representation.
16pub struct DefaultFloatFormat;
17impl FloatFormat for DefaultFloatFormat {
18    fn write_f64(f: &mut impl core::fmt::Write, value: f64) -> core::fmt::Result {
19        const UPPER_BOUND_LIT:f64 = 1e6;
20        const LOWER_BOUND_LIT:f64 = 1e-3;
21
22        if value.is_finite() {
23            if value.abs() < UPPER_BOUND_LIT && value.abs() >= LOWER_BOUND_LIT {
24                write!(f, "{}", value)
25            }
26            else {
27                write!(f, "{:e}", value)
28            }
29        }
30        else {
31            write!(f, "null")
32        }
33    }
34
35    fn write_f32(f: &mut impl core::fmt::Write, value: f32) -> core::fmt::Result {
36        const UPPER_BOUND_LIT:f32 = 1e6;
37        const LOWER_BOUND_LIT:f32 = 1e-3;
38
39        if value.is_finite() {
40            if value.abs() < UPPER_BOUND_LIT && value.abs() >= LOWER_BOUND_LIT {
41                write!(f, "{}", value)
42            }
43            else {
44                write!(f, "{:e}", value)
45            }
46        }
47        else {
48            write!(f, "null")
49        }
50    }
51}