xsd_types/value/
double.rs1use std::{
2 borrow::Borrow,
3 fmt,
4 ops::{Add, Deref, DerefMut, Div, Mul, Sub},
5 str::FromStr,
6};
7
8use ordered_float::OrderedFloat;
9
10use crate::{
11 lexical::{self, LexicalFormOf},
12 Datatype, ParseXsd, XsdValue,
13};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct Double(OrderedFloat<f64>);
17
18impl Double {
19 pub const NEG_INFINITY: Self = Self(OrderedFloat(f64::NEG_INFINITY));
20 pub const INFINITY: Self = Self(OrderedFloat(f64::INFINITY));
21 pub const MIN: Self = Self(OrderedFloat(f64::MIN));
22 pub const MAX: Self = Self(OrderedFloat(f64::MAX));
23 pub const NAN: Self = Self(OrderedFloat(f64::NAN));
24
25 #[inline(always)]
26 pub fn new(f: f64) -> Self {
27 Self(OrderedFloat(f))
28 }
29
30 #[inline(always)]
32 pub fn is_nan(&self) -> bool {
33 self.0 .0.is_nan()
34 }
35
36 #[inline(always)]
38 pub fn is_finite(&self) -> bool {
39 self.0 .0.is_finite()
40 }
41
42 #[inline(always)]
44 pub fn is_infinite(&self) -> bool {
45 self.0 .0.is_infinite()
46 }
47
48 #[inline(always)]
59 pub fn is_positive(&self) -> bool {
60 self.0 .0.is_sign_positive()
61 }
62
63 #[inline(always)]
74 pub fn is_negative(&self) -> bool {
75 self.0 .0.is_sign_negative()
76 }
77
78 #[inline(always)]
80 pub const fn into_f64(self) -> f64 {
81 self.0 .0
82 }
83}
84
85const XSD_CANONICAL_DOUBLE: pretty_dtoa::FmtFloatConfig = pretty_dtoa::FmtFloatConfig::default()
87 .force_e_notation()
88 .capitalize_e(true);
89
90impl fmt::Display for Double {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 pretty_dtoa::dtoa(self.0 .0, XSD_CANONICAL_DOUBLE).fmt(f)
93 }
94}
95
96impl XsdValue for Double {
97 fn datatype(&self) -> Datatype {
98 Datatype::Double
99 }
100}
101
102impl ParseXsd for Double {
103 type LexicalForm = lexical::Double;
104}
105
106impl LexicalFormOf<Double> for lexical::Double {
107 type ValueError = std::convert::Infallible;
108
109 fn try_as_value(&self) -> Result<Double, Self::ValueError> {
110 Ok(self.value())
111 }
112}
113
114impl<'a> From<&'a lexical::Double> for Double {
115 fn from(value: &'a lexical::Double) -> Self {
116 Self::new(value.into())
117 }
118}
119
120impl From<lexical::DoubleBuf> for Double {
121 fn from(value: lexical::DoubleBuf) -> Self {
122 Self::new(value.into())
123 }
124}
125
126impl FromStr for Double {
127 type Err = lexical::InvalidDouble;
128
129 fn from_str(s: &str) -> Result<Self, Self::Err> {
130 let l = lexical::Double::new(s)?;
131 Ok(l.into())
132 }
133}
134
135impl From<f32> for Double {
136 fn from(value: f32) -> Self {
137 Self(OrderedFloat(value as f64))
138 }
139}
140
141impl From<f64> for Double {
142 fn from(value: f64) -> Self {
143 Self(OrderedFloat(value))
144 }
145}
146
147impl From<Double> for f64 {
148 fn from(value: Double) -> Self {
149 value.0 .0
150 }
151}
152
153impl AsRef<f64> for Double {
154 fn as_ref(&self) -> &f64 {
155 &self.0
156 }
157}
158
159impl Borrow<f64> for Double {
160 fn borrow(&self) -> &f64 {
161 &self.0
162 }
163}
164
165impl Deref for Double {
166 type Target = f64;
167
168 fn deref(&self) -> &f64 {
169 &self.0
170 }
171}
172
173impl DerefMut for Double {
174 fn deref_mut(&mut self) -> &mut f64 {
175 &mut self.0
176 }
177}
178
179impl Add for Double {
180 type Output = Self;
181
182 fn add(self, rhs: Self) -> Self::Output {
183 Self(OrderedFloat(*self.0 + *rhs.0))
184 }
185}
186
187impl Sub for Double {
188 type Output = Self;
189
190 fn sub(self, rhs: Self) -> Self::Output {
191 Self(OrderedFloat(*self.0 - *rhs.0))
192 }
193}
194
195impl Mul for Double {
196 type Output = Self;
197
198 fn mul(self, rhs: Self) -> Self::Output {
199 Self(OrderedFloat(*self.0 * *rhs.0))
200 }
201}
202
203impl Div for Double {
204 type Output = Self;
205
206 fn div(self, rhs: Self) -> Self::Output {
207 Self(OrderedFloat(*self.0 / *rhs.0))
208 }
209}