pub struct Decimal<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32>(/* private fields */);Expand description
Decimal number with at most MAX_DIGITS significant digits and at most
DECIMAL_PLACES digits after the decimal point.
Why strings in strict mode. JSON numbers are IEEE-754 floats in
serde_json (this crate does not enable arbitrary_precision), so values
such as 1.1 cannot be represented exactly. Strict mode therefore accepts
only JSON strings; lax mode also accepts numbers and converts them through
f64, which may round.
Trailing zeros are ignored when checking digits, matching Pydantic
(1.20 satisfies DECIMAL_PLACES = 1). Unlike Pydantic, integer digits
are not additionally capped at MAX_DIGITS - DECIMAL_PLACES.
The JSON Schema is {"type":"string","format":"decimal"}. format is an
application hint (not a JSON Schema 2020-12 built-in); a pattern is
omitted because [rust_decimal] also accepts scientific notation.
Implementations§
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Decimal<MAX_DIGITS, DECIMAL_PLACES>
Sourcepub fn new(value: RawDecimal) -> Result<Self, FieldError>
pub fn new(value: RawDecimal) -> Result<Self, FieldError>
Validate digit constraints and wrap value.
Sourcepub fn parse(value: &str) -> Result<Self, FieldError>
pub fn parse(value: &str) -> Result<Self, FieldError>
Parse a decimal string and validate digit constraints.
Methods from Deref<Target = RawDecimal>§
pub const MIN: Decimal = MIN
pub const MAX: Decimal = MAX
pub const ZERO: Decimal = ZERO
pub const ONE: Decimal = ONE
pub const NEGATIVE_ONE: Decimal = NEGATIVE_ONE
pub const TWO: Decimal = TWO
pub const TEN: Decimal = TEN
pub const ONE_HUNDRED: Decimal = ONE_HUNDRED
pub const ONE_THOUSAND: Decimal = ONE_THOUSAND
pub const MAX_SCALE: u32 = MAX_SCALE_U32
pub const PI: Decimal
pub const HALF_PI: Decimal
pub const QUARTER_PI: Decimal
pub const TWO_PI: Decimal
pub const E: Decimal
pub const E_INVERSE: Decimal
pub fn array_string(&self) -> impl AsRef<str>
pub fn array_string(&self) -> impl AsRef<str>
Returns a string representation that is similar to alloc::string::ToString but
doesn’t require a heap allocation.
§Examples
assert_eq!(Decimal::from_str_exact("-0.001")?.array_string().as_ref(), "-0.001");pub fn scale(&self) -> u32
pub fn scale(&self) -> u32
Returns the scale of the decimal number, otherwise known as e.
§Example
let num = Decimal::new(1234, 3);
assert_eq!(num.scale(), 3u32);pub fn mantissa(&self) -> i128
pub fn mantissa(&self) -> i128
Returns the mantissa of the decimal number.
§Example
let num = dec!(-1.2345678);
assert_eq!(num.mantissa(), -12345678i128);
assert_eq!(num.scale(), 7);pub fn is_zero(&self) -> bool
pub fn is_zero(&self) -> bool
Returns true if this Decimal number is equivalent to zero.
§Example
let num = Decimal::ZERO;
assert!(num.is_zero());pub fn is_integer(&self) -> bool
pub fn is_integer(&self) -> bool
Returns true if this Decimal number has zero fractional part (is equal to an integer)
§Example
assert_eq!(dec!(5).is_integer(), true);
// Trailing zeros are also ignored
assert_eq!(dec!(5.0000).is_integer(), true);
// If there is a fractional part then it is not an integer
assert_eq!(dec!(5.1).is_integer(), false);pub fn serialize(&self) -> [u8; 16]
pub fn serialize(&self) -> [u8; 16]
Returns a serialized version of the decimal number. The resulting byte array will have the following representation:
- Bytes 1-4: flags
- Bytes 5-8: lo portion of
m - Bytes 9-12: mid portion of
m - Bytes 13-16: high portion of
m
pub fn is_negative(&self) -> bool
👎Deprecated since 0.6.3: please use is_sign_negative instead
pub fn is_negative(&self) -> bool
please use is_sign_negative instead
Returns true if the decimal is negative.
pub fn is_positive(&self) -> bool
👎Deprecated since 0.6.3: please use is_sign_positive instead
pub fn is_positive(&self) -> bool
please use is_sign_positive instead
Returns true if the decimal is positive.
pub fn is_sign_negative(&self) -> bool
pub fn is_sign_negative(&self) -> bool
Returns true if the sign bit of the decimal is negative.
§Example
assert_eq!(true, Decimal::new(-1, 0).is_sign_negative());
assert_eq!(false, Decimal::new(1, 0).is_sign_negative());pub fn is_sign_positive(&self) -> bool
pub fn is_sign_positive(&self) -> bool
Returns true if the sign bit of the decimal is positive.
§Example
assert_eq!(false, Decimal::new(-1, 0).is_sign_positive());
assert_eq!(true, Decimal::new(1, 0).is_sign_positive());pub fn trunc(&self) -> Decimal
pub fn trunc(&self) -> Decimal
Returns a new Decimal integral with no fractional portion.
This is a true truncation whereby no rounding is performed.
§Example
let pi = dec!(3.141);
assert_eq!(pi.trunc(), dec!(3));
// Negative numbers are similarly truncated without rounding
let neg = dec!(-1.98765);
assert_eq!(neg.trunc(), Decimal::NEGATIVE_ONE);pub fn trunc_with_scale(&self, scale: u32) -> Decimal
pub fn trunc_with_scale(&self, scale: u32) -> Decimal
Returns a new Decimal with the fractional portion delimited by scale.
This is a true truncation whereby no rounding is performed.
§Example
let pi = dec!(3.141592);
assert_eq!(pi.trunc_with_scale(2), dec!(3.14));
// Negative numbers are similarly truncated without rounding
let neg = dec!(-1.98765);
assert_eq!(neg.trunc_with_scale(1), dec!(-1.9));pub fn fract(&self) -> Decimal
pub fn fract(&self) -> Decimal
Returns a new Decimal representing the fractional portion of the number.
§Example
let pi = Decimal::new(3141, 3);
let fract = Decimal::new(141, 3);
// note that it returns a decimal
assert_eq!(pi.fract(), fract);pub fn abs(&self) -> Decimal
pub fn abs(&self) -> Decimal
Computes the absolute value of self.
§Example
let num = Decimal::new(-3141, 3);
assert_eq!(num.abs().to_string(), "3.141");pub fn floor(&self) -> Decimal
pub fn floor(&self) -> Decimal
Returns the largest integer less than or equal to a number.
§Example
let num = Decimal::new(3641, 3);
assert_eq!(num.floor().to_string(), "3");pub fn ceil(&self) -> Decimal
pub fn ceil(&self) -> Decimal
Returns the smallest integer greater than or equal to a number.
§Example
let num = Decimal::new(3141, 3);
assert_eq!(num.ceil().to_string(), "4");
let num = Decimal::new(3, 0);
assert_eq!(num.ceil().to_string(), "3");pub fn normalize(&self) -> Decimal
pub fn normalize(&self) -> Decimal
Strips any trailing zero’s from a Decimal and converts -0 to 0.
§Example
let number = Decimal::from_str("3.100")?;
assert_eq!(number.normalize().to_string(), "3.1");pub fn round(&self) -> Decimal
pub fn round(&self) -> Decimal
Returns a new Decimal number with no fractional portion (i.e. an integer).
Rounding currently follows “Bankers Rounding” rules. e.g. 6.5 -> 6, 7.5 -> 8
§Example
// Demonstrating bankers rounding...
let number_down = Decimal::new(65, 1);
let number_up = Decimal::new(75, 1);
assert_eq!(number_down.round().to_string(), "6");
assert_eq!(number_up.round().to_string(), "8");pub fn round_dp_with_strategy(
&self,
dp: u32,
strategy: RoundingStrategy,
) -> Decimal
pub fn round_dp_with_strategy( &self, dp: u32, strategy: RoundingStrategy, ) -> Decimal
Returns a new Decimal number with the specified number of decimal points for fractional
portion.
Rounding is performed using the provided [RoundingStrategy]
§Arguments
dp: the number of decimal points to round to.strategy: the [RoundingStrategy] to use.
§Example
let tax = dec!(3.4395);
assert_eq!(tax.round_dp_with_strategy(2, RoundingStrategy::MidpointAwayFromZero).to_string(), "3.44");pub fn round_dp(&self, dp: u32) -> Decimal
pub fn round_dp(&self, dp: u32) -> Decimal
Returns a new Decimal number with the specified number of decimal points for fractional portion.
Rounding currently follows “Bankers Rounding” rules. e.g. 6.5 -> 6, 7.5 -> 8
§Arguments
dp: the number of decimal points to round to.
§Example
let pi = dec!(3.1415926535897932384626433832);
assert_eq!(pi.round_dp(2).to_string(), "3.14");pub fn round_sf(&self, digits: u32) -> Option<Decimal>
pub fn round_sf(&self, digits: u32) -> Option<Decimal>
Returns Some(Decimal) number rounded to the specified number of significant digits. If
the resulting number is unable to be represented by the Decimal number then None will
be returned.
When the number of significant figures of the Decimal being rounded is greater than the requested
number of significant digits then rounding will be performed using MidpointNearestEven strategy.
§Arguments
digits: the number of significant digits to round to.
§Remarks
A significant figure is determined using the following rules:
- Non-zero digits are always significant.
- Zeros between non-zero digits are always significant.
- Leading zeros are never significant.
- Trailing zeros are only significant if the number contains a decimal point.
§Example
let value = dec!(305.459);
assert_eq!(value.round_sf(0), Some(dec!(0)));
assert_eq!(value.round_sf(1), Some(dec!(300)));
assert_eq!(value.round_sf(2), Some(dec!(310)));
assert_eq!(value.round_sf(3), Some(dec!(305)));
assert_eq!(value.round_sf(4), Some(dec!(305.5)));
assert_eq!(value.round_sf(5), Some(dec!(305.46)));
assert_eq!(value.round_sf(6), Some(dec!(305.459)));
assert_eq!(value.round_sf(7), Some(dec!(305.4590)));
assert_eq!(Decimal::MAX.round_sf(1), None);
let value = dec!(0.012301);
assert_eq!(value.round_sf(3), Some(dec!(0.0123)));pub fn round_sf_with_strategy(
&self,
digits: u32,
strategy: RoundingStrategy,
) -> Option<Decimal>
pub fn round_sf_with_strategy( &self, digits: u32, strategy: RoundingStrategy, ) -> Option<Decimal>
Returns Some(Decimal) number rounded to the specified number of significant digits. If
the resulting number is unable to be represented by the Decimal number then None will
be returned.
When the number of significant figures of the Decimal being rounded is greater than the requested
number of significant digits then rounding will be performed using the provided [RoundingStrategy].
§Arguments
digits: the number of significant digits to round to.strategy: if required, the rounding strategy to use.
§Remarks
A significant figure is determined using the following rules:
- Non-zero digits are always significant.
- Zeros between non-zero digits are always significant.
- Leading zeros are never significant.
- Trailing zeros are only significant if the number contains a decimal point.
§Example
let value = dec!(305.459);
assert_eq!(value.round_sf_with_strategy(0, RoundingStrategy::ToZero), Some(dec!(0)));
assert_eq!(value.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(300)));
assert_eq!(value.round_sf_with_strategy(2, RoundingStrategy::ToZero), Some(dec!(300)));
assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::ToZero), Some(dec!(305)));
assert_eq!(value.round_sf_with_strategy(4, RoundingStrategy::ToZero), Some(dec!(305.4)));
assert_eq!(value.round_sf_with_strategy(5, RoundingStrategy::ToZero), Some(dec!(305.45)));
assert_eq!(value.round_sf_with_strategy(6, RoundingStrategy::ToZero), Some(dec!(305.459)));
assert_eq!(value.round_sf_with_strategy(7, RoundingStrategy::ToZero), Some(dec!(305.4590)));
assert_eq!(Decimal::MAX.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(70000000000000000000000000000)));
let value = dec!(0.012301);
assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::AwayFromZero), Some(dec!(0.0124)));pub fn unpack(&self) -> UnpackedDecimal
pub fn unpack(&self) -> UnpackedDecimal
Convert Decimal to an internal representation of the underlying struct. This is useful
for debugging the internal state of the object.
§Important Disclaimer
This is primarily intended for library maintainers. The internal representation of a
Decimal is considered “unstable” for public use.
§Example
let pi = dec!(3.1415926535897932384626433832);
assert_eq!(format!("{:?}", pi), "3.1415926535897932384626433832");
assert_eq!(format!("{:?}", pi.unpack()), "UnpackedDecimal { \
negative: false, scale: 28, hi: 1703060790, mid: 185874565, lo: 1102470952 \
}");pub fn as_i128(&self) -> i128
pub fn as_i128(&self) -> i128
Converts this Decimal to an i128, truncating any fractional part.
This is the infallible equivalent of ToPrimitive::to_i128.
pub fn as_f64(&self) -> f64
pub fn as_f64(&self) -> f64
Converts this Decimal to an f64.
This is the infallible equivalent of ToPrimitive::to_f64.
Trait Implementations§
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> AsRef<Decimal> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> AsRef<Decimal> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Clone for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Clone for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Copy for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Debug for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Debug for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Deref for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Deref for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<'de, const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Deserialize<'de> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<'de, const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Deserialize<'de> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Display for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Display for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Dump for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Dump for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§fn serialize_dump<S: Serializer>(
&self,
serializer: S,
opts: &DumpOptions,
) -> Result<S::Ok, S::Error>
fn serialize_dump<S: Serializer>( &self, serializer: S, opts: &DumpOptions, ) -> Result<S::Ok, S::Error>
dump semantics. Read moreimpl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Eq for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> From<Decimal<MAX_DIGITS, DECIMAL_PLACES>> for Decimal
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> From<Decimal<MAX_DIGITS, DECIMAL_PLACES>> for Decimal
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> From<Decimal<MAX_DIGITS, DECIMAL_PLACES>> for String
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> From<Decimal<MAX_DIGITS, DECIMAL_PLACES>> for String
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Hash for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Hash for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Ord for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Ord for Decimal<MAX_DIGITS, DECIMAL_PLACES>
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> PartialEq for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> PartialEq for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> PartialOrd for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> PartialOrd for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Schema for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Schema for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§fn schema(_: &mut SchemaRegistry) -> SchemaObject
fn schema(_: &mut SchemaRegistry) -> SchemaObject
SchemaRegistry::subschema for nested types.Source§fn schema_name() -> Option<&'static str>
fn schema_name() -> Option<&'static str>
components.schemas and referenced with $ref.Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Serialize for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Serialize for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> StructuralPartialEq for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<&str> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<&str> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<Decimal> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<Decimal> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<String> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> TryFrom<String> for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Validate for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Validate for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Source§fn prepare(input: &mut Value, ctx: &mut ValidationContext)
fn prepare(input: &mut Value, ctx: &mut ValidationContext)
Source§fn validate(&self, _ctx: &mut ValidationContext)
fn validate(&self, _ctx: &mut ValidationContext)
Auto Trait Implementations§
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Freeze for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> RefUnwindSafe for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Send for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Sync for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> Unpin for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> UnsafeUnpin for Decimal<MAX_DIGITS, DECIMAL_PLACES>
impl<const MAX_DIGITS: u32, const DECIMAL_PLACES: u32> UnwindSafe for Decimal<MAX_DIGITS, DECIMAL_PLACES>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.