apple_plist/value/
real.rs1use std::cmp::Ordering;
4
5#[derive(Clone, Copy, Debug)]
25pub struct Real {
26 value: f64,
27 wide: bool,
28}
29
30impl Real {
31 #[must_use]
42 pub const fn value(self) -> f64 {
43 self.value
44 }
45
46 #[cfg_attr(
49 not(any(test, feature = "serde", feature = "binary")),
50 expect(
51 dead_code,
52 reason = "consumed by the serde bridge and the binary codec; dead only when both are compiled out"
53 )
54 )]
55 pub(crate) const fn wide(self) -> bool {
56 self.wide
57 }
58}
59
60impl From<f32> for Real {
61 fn from(value: f32) -> Self {
62 Self {
63 value: f64::from(value),
64 wide: false,
65 }
66 }
67}
68
69impl From<f64> for Real {
70 fn from(value: f64) -> Self {
71 Self { value, wide: true }
72 }
73}
74
75impl PartialEq for Real {
76 fn eq(&self, other: &Self) -> bool {
78 self.value == other.value
79 }
80}
81
82impl PartialOrd for Real {
83 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
84 self.value.partial_cmp(&other.value)
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 #![expect(clippy::float_cmp, reason = "test code: bit-exact float expectations")]
91
92 use super::*;
93
94 #[test]
95 fn width_follows_the_source_type() {
96 assert!(!Real::from(32.0f32).wide());
97 assert!(Real::from(32.0f64).wide());
98 }
99
100 #[test]
101 fn narrow_construction_widens_exactly() {
102 assert_eq!(Real::from(f32::MAX).value(), f64::from(f32::MAX));
103 assert_eq!(Real::from(0.5f32).value(), 0.5);
104 }
105
106 #[test]
107 fn equality_is_numeric_and_ignores_width() {
108 assert_eq!(Real::from(32.0f32), Real::from(32.0f64));
109 assert_ne!(Real::from(32.0f64), Real::from(64.0f64));
110 assert_eq!(Real::from(-0.0f64), Real::from(0.0f64));
111 }
112
113 #[test]
114 fn nan_is_not_equal_to_itself() {
115 let nan = Real::from(f64::NAN);
116 assert_ne!(nan, nan);
117 assert_eq!(nan.partial_cmp(&nan), None);
118 }
119
120 #[test]
121 fn ordering_is_numeric() {
122 assert!(Real::from(1.0f32) < Real::from(2.0f64));
123 assert_eq!(
124 Real::from(2.0f32).partial_cmp(&Real::from(2.0f64)),
125 Some(Ordering::Equal)
126 );
127 }
128}