/// A structured field value [decimal]. /// /// Decimals have 12 digits of integer precision and 3 digits of fractional precision. /// /// [decimal]: <https://httpwg.org/specs/rfc9651.html#decimal> #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pubstruct Decimal(Integer);
impl Decimal { /// The minimum value for a parsed or serialized decimal: `-999_999_999_999.999`. pubconst MIN: Self = Self::from_integer_scaled_1000(Integer::MIN);
/// The maximum value for a parsed or serialized decimal: `999_999_999_999.999`. pubconst MAX: Self = Self::from_integer_scaled_1000(Integer::MAX);
/// Returns the decimal as an integer multiplied by 1000. /// /// The conversion is guaranteed to be precise. /// /// # Example /// /// ``` /// let decimal = sfv::Decimal::try_from(1.234).unwrap(); /// assert_eq!(i64::try_from(decimal.as_integer_scaled_1000()).unwrap(), 1234); /// ``` #[must_use] pubfn as_integer_scaled_1000(&self) -> Integer { self.0
}
/// Creates a decimal from an integer multiplied by 1000. /// /// The conversion is guaranteed to be precise. /// /// # Example /// /// ``` /// let decimal = sfv::Decimal::from_integer_scaled_1000(sfv::integer(1234)); /// #[allow(clippy::float_cmp)] /// assert_eq!(f64::try_from(decimal).unwrap(), 1.234); /// ``` #[must_use] pubconstfn from_integer_scaled_1000(v: Integer) -> Self { Self(v)
}
}
impl fmt::Display for Decimal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let v = i64::from(self.as_integer_scaled_1000());
if v == 0 { return f.write_str("0.0");
}
let sign = if v < 0 { "-" } else { "" }; let v = v.abs(); let i_part = v / 1000; let f_part = v % 1000;
impl From<Decimal> for f64 { #[allow(clippy::cast_precision_loss)] fn from(v: Decimal) -> Self { let v = i64::from(v.as_integer_scaled_1000());
(v as f64) / 1000.0
}
}
impl TryFrom<f32> for Decimal { type Error = Error;
let v = (v * 1000.0).round_ties_even(); // Only excessively clever options exist for this conversion, so use "as" // Note that this relies on saturating casts for values > i64::MAX // See https://github.com/rust-lang/rust/issues/10184 #[allow(clippy::cast_possible_truncation)]
Integer::try_from(v as i64).map(Decimal)
}
}
impl TryFrom<Integer> for Decimal { type Error = Error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.