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