1#![allow(clippy::float_cmp)]
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[rustfmt::skip] // appears to be a bug in rustfmt to make this converge...
7macro_rules! float_inf_tests {
8 ($ty:ty) => {{
9 #[derive(Serialize, Deserialize)]
10 struct S {
11 sf1: $ty,
12 sf2: $ty,
13 sf3: $ty,
14 sf4: $ty,
15 sf5: $ty,
16 sf6: $ty,
17 sf7: $ty,
18 sf8: $ty,
19 }
20 let inf: S = basic_toml::from_str(
21 "
22 # infinity
23 sf1 = inf # positive infinity
24 sf2 = +inf # positive infinity
25 sf3 = -inf # negative infinity
26
27 # not a number
28 sf4 = nan # actual sNaN/qNaN encoding is implementation specific
29 sf5 = +nan # same as `nan`
30 sf6 = -nan # valid, actual encoding is implementation specific
31
32 # zero
33 sf7 = +0.0
34 sf8 = -0.0
35 ",
36 )
37 .expect("Parse infinities.");
38
39 assert!(inf.sf1.is_infinite());
40 assert!(inf.sf1.is_sign_positive());
41 assert!(inf.sf2.is_infinite());
42 assert!(inf.sf2.is_sign_positive());
43 assert!(inf.sf3.is_infinite());
44 assert!(inf.sf3.is_sign_negative());
45
46 assert!(inf.sf4.is_nan());
47 assert!(inf.sf4.is_sign_positive());
48 assert!(inf.sf5.is_nan());
49 assert!(inf.sf5.is_sign_positive());
50 assert!(inf.sf6.is_nan());
51 assert!(inf.sf6.is_sign_negative()); // NOTE: but serializes to just `nan`
52
53 assert_eq!(inf.sf7, 0.0);
54 assert!(inf.sf7.is_sign_positive());
55 assert_eq!(inf.sf8, 0.0);
56 assert!(inf.sf8.is_sign_negative());
57
58 let s = basic_toml::to_string(&inf).unwrap();
59 assert_eq!(
60 s,
61 "\
62sf1 = inf
63sf2 = inf
64sf3 = -inf
65sf4 = nan
66sf5 = nan
67sf6 = nan
68sf7 = 0.0
69sf8 = -0.0
70"
71 );
72
73 basic_toml::from_str::<Value>(&s).expect("roundtrip");
74 }};
75}
76
77#[test]
78fn float_inf() {
79 float_inf_tests!(f32);
80 float_inf_tests!(f64);
81}
82