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