pub struct RawMoney<C: Currency> { /* private fields */ }Expand description
Represents a monetary value without automatic rounding.
RawMoney is exactly like Money except it doesn’t automatically round
amounts after each operation. It keeps full decimal precision and lets
callers decide when to round.
§Key Features
- Type Safety: Provides compile-time checks to ensure valid state.
- Precision: Uses 128-bit fixed-precision decimal for accurate calculations.
- No Automatic Rounding: Preserves all decimal places until explicitly rounded.
- Zero-Cost:
Copytype with no heap allocations and currency metadata is zero-sized type.
§Conversion
- Convert from
MoneyusingMoney::into_raw - Convert to
MoneyusingRawMoney::finish(applies rounding)
§Where Rounding Happens
BaseMoney::round: rounds using currency’s minor unit (bankers rounding). ReturnsRawMoney.BaseMoney::round_with: rounds using custom decimal points and strategy. ReturnsRawMoney.RawMoney::finish: rounds to currency’s minor unit using bankers rounding back toMoney.
§Examples
use moneylib::{Money, RawMoney, BaseMoney, macros::dec, iso::USD};
// Create RawMoney directly - no rounding
let raw = RawMoney::<USD>::new(dec!(100.567)).unwrap();
assert_eq!(raw.amount(), dec!(100.567));
// Convert from Money
let money = Money::<USD>::new(dec!(100.50)).unwrap();
let raw = money.into_raw();
assert_eq!(raw.amount(), dec!(100.50));
// Convert back to Money with rounding
let raw = RawMoney::<USD>::new(dec!(100.567)).unwrap();
let money = raw.finish();
assert_eq!(money.amount(), dec!(100.57));§See Also
Moneyfor automatically-rounded monetary valuesBaseMoneytrait for core money operations and accessorsBaseOpstrait for arithmetic and comparison operationsMoneyFormattertrait for custom formatting and rounding
Implementations§
Source§impl<C> RawMoney<C>where
C: Currency,
impl<C> RawMoney<C>where
C: Currency,
Sourcepub const fn from_decimal(amount: Decimal) -> Self
pub const fn from_decimal(amount: Decimal) -> Self
Creates a new RawMoney instance from Decimal without rounding.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::USD};
let raw = RawMoney::<USD>::from_decimal(dec!(123.309));
assert_eq!(raw.amount(), dec!(123.309));Sourcepub fn from_minor(minor_amount: i128) -> Result<Self, MoneyError>
pub fn from_minor(minor_amount: i128) -> Result<Self, MoneyError>
Creates a new RawMoney from minor amount i128 without rounding.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::{USD, BHD, JPY}};
// USD has 2 decimal places, so 12302 cents = $123.02
let raw = RawMoney::<USD>::from_minor(12302).unwrap();
assert_eq!(raw.amount(), dec!(123.02));
// JPY has 0 decimal places
let raw = RawMoney::<JPY>::from_minor(1000).unwrap();
assert_eq!(raw.amount(), dec!(1000));
// BHD has 3 decimal places
let raw = RawMoney::<BHD>::from_minor(12345).unwrap();
assert_eq!(raw.amount(), dec!(12.345));Sourcepub fn finish(self) -> Money<C>
pub fn finish(self) -> Money<C>
Converts this RawMoney to Money, applying rounding.
Rounds the amount to the currency’s minor unit precision using the
bankers rounding rule, then returns a Money instance.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::{USD, JPY, BHD}};
let raw = RawMoney::<USD>::new(dec!(100.567)).unwrap();
let money = raw.finish();
assert_eq!(money.amount(), dec!(100.57));
let raw_jpy = RawMoney::<JPY>::new(dec!(100.567)).unwrap();
let money = raw_jpy.finish();
assert_eq!(money.amount(), dec!(101));
let raw_bhd = RawMoney::<BHD>::new(dec!(100.9999)).unwrap();
let money = raw_bhd.finish();
assert_eq!(money.amount(), dec!(101.000));Sourcepub fn from_code_comma_thousands(s: &str) -> Result<Self, MoneyError>
pub fn from_code_comma_thousands(s: &str) -> Result<Self, MoneyError>
Parses a string in the format "CCC amount" (comma thousands separator and dot decimal separator).
The format is "CCC amount" where CCC is a currency code (1-15 letters).
For dot thousands separator format (e.g., "EUR 1.234,56"), use
RawMoney::from_code_dot_thousands instead.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::USD};
use std::str::FromStr;
let raw = RawMoney::<USD>::from_code_comma_thousands("USD 1,234.56789").unwrap();
assert_eq!(raw.amount(), dec!(1234.56789));
assert_eq!(raw.code(), "USD");
assert!(RawMoney::<USD>::from_code_comma_thousands("EUR 100.00").is_err());Sourcepub fn from_code_dot_thousands(s: &str) -> Result<Self, MoneyError>
pub fn from_code_dot_thousands(s: &str) -> Result<Self, MoneyError>
Creates a new RawMoney from a string with dot as the thousands separator
and comma as the decimal separator (e.g., "EUR 1.234,56").
The format is "CCC amount" where CCC is a currency code (1-15 letters) and
§Examples
use moneylib::{RawMoney, BaseMoney, iso::{EUR, USD}};
let raw = RawMoney::<EUR>::from_code_dot_thousands("EUR 1.234,56").unwrap();
assert_eq!(raw.code(), "EUR");
assert!(RawMoney::<USD>::from_code_dot_thousands("EUR 1.234,56").is_err());Sourcepub fn from_symbol_comma_thousands(s: &str) -> Result<Self, MoneyError>
pub fn from_symbol_comma_thousands(s: &str) -> Result<Self, MoneyError>
Parse from string with symbol, comma-separated thousands, dot-separated decimal, no rounding Example: $1,234.2249 into USD 1234.2249
Sourcepub fn from_symbol_dot_thousands(s: &str) -> Result<Self, MoneyError>
pub fn from_symbol_dot_thousands(s: &str) -> Result<Self, MoneyError>
Parse from string with symbol, dot-separated thousands, comma-separated decimal, no rounding Example: $1.234,2249 into USD 1234.2249
Sourcepub fn from_code_locale_separator(s: &str) -> Result<Self, MoneyError>
pub fn from_code_locale_separator(s: &str) -> Result<Self, MoneyError>
Parse from string with code, locale thousands and decimal separators.
Code is space separated with amount.
Currencies locale separators are from here: https://docs.rs/currencylib
§Example
use moneylib::{RawMoney, raw, iso::CHF, dec, BaseMoney};
let money = RawMoney::<CHF>::from_code_locale_separator("CHF 1'123'456.2223").unwrap();
assert_eq!(money.code(), "CHF");
assert_eq!(money.symbol(), "₣");
assert_eq!(money.amount(), dec!(1123456.2223));
assert_eq!(money, raw!(CHF, 1123456.2223));Sourcepub fn from_symbol_locale_separator(s: &str) -> Result<Self, MoneyError>
pub fn from_symbol_locale_separator(s: &str) -> Result<Self, MoneyError>
Parse from string with symbol, locale thousands and decimal separators.
There’s no space between symbol and amount.
Currencies locale separators are from here: https://docs.rs/currencylib
§Example
use moneylib::{RawMoney, raw, iso::CHF, dec, BaseMoney};
let money = RawMoney::<CHF>::from_symbol_locale_separator("₣1'123'456.2223").unwrap();
assert_eq!(money.code(), "CHF");
assert_eq!(money.symbol(), "₣");
assert_eq!(money.amount(), dec!(1123456.2223));
assert_eq!(money, raw!(CHF, 1123456.2223));Trait Implementations§
Source§impl<C> Add for RawMoney<C>where
C: Currency,
RawMoney + RawMoney = RawMoney (no auto-rounding)
impl<C> Add for RawMoney<C>where
C: Currency,
RawMoney + RawMoney = RawMoney (no auto-rounding)
Source§impl<C> AddAssign for RawMoney<C>where
C: Currency,
RawMoney += RawMoney (no auto-rounding)
impl<C> AddAssign for RawMoney<C>where
C: Currency,
RawMoney += RawMoney (no auto-rounding)
Source§fn add_assign(&mut self, other: Self)
fn add_assign(&mut self, other: Self)
+= operation. Read moreSource§impl<C> BaseMoney<C> for RawMoney<C>where
C: Currency,
impl<C> BaseMoney<C> for RawMoney<C>where
C: Currency,
Source§fn round(self) -> Self
fn round(self) -> Self
Rounds explicitly to the currency’s minor unit using bankers rounding.
Unlike Money, this must be called explicitly. Returns RawMoney.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::USD};
let raw = RawMoney::<USD>::from_decimal(dec!(100.567));
let rounded = raw.round();
assert_eq!(rounded.amount(), dec!(100.57));
// round() returns RawMoney, not Money
let rounded_again = rounded.round();
assert_eq!(rounded_again.amount(), dec!(100.57));Source§fn minor_amount(&self) -> Option<i128>
fn minor_amount(&self) -> Option<i128>
Returns the money amount in its smallest unit, rounding as needed.
Since minor amounts must be integers, this rounds the raw amount to the currency’s minor unit precision before computing the minor amount.
§Examples
use moneylib::{RawMoney, BaseMoney, macros::dec, iso::USD};
let raw = RawMoney::<USD>::from_decimal(dec!(123.45));
assert_eq!(raw.minor_amount().unwrap(), 12345_i128);
// Extra precision is rounded before computing minor amount
let raw = RawMoney::<USD>::from_decimal(dec!(123.238533));
assert_eq!(raw.minor_amount().unwrap(), 12324_i128);Source§fn new(amount: impl DecimalNumber) -> Result<Self, MoneyError>
fn new(amount: impl DecimalNumber) -> Result<Self, MoneyError>
Source§fn round_with(self, decimal_points: u32, strategy: RoundingStrategy) -> Self
fn round_with(self, decimal_points: u32, strategy: RoundingStrategy) -> Self
Source§fn truncate_with(&self, scale: u32) -> Self
fn truncate_with(&self, scale: u32) -> Self
Source§fn numeric_code(&self) -> i32
fn numeric_code(&self) -> i32
Source§fn minor_unit(&self) -> u16
fn minor_unit(&self) -> u16
Source§fn thousand_separator(&self) -> &str
fn thousand_separator(&self) -> &str
Source§fn decimal_separator(&self) -> &str
fn decimal_separator(&self) -> &str
Source§fn is_positive(&self) -> bool
fn is_positive(&self) -> bool
true if the amount is positive. Read moreSource§fn is_negative(&self) -> bool
fn is_negative(&self) -> bool
true if the amount is negative. Read moreSource§fn format_code(&self) -> String
fn format_code(&self) -> String
Source§fn format_symbol(&self) -> String
fn format_symbol(&self) -> String
Source§fn format_code_minor(&self) -> String
fn format_code_minor(&self) -> String
Source§fn format_symbol_minor(&self) -> String
fn format_symbol_minor(&self) -> String
Source§impl<C> BaseOps<C> for RawMoney<C>where
C: Currency,
impl<C> BaseOps<C> for RawMoney<C>where
C: Currency,
Source§fn checked_add<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: Amount<C>,
fn checked_add<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: Amount<C>,
Source§fn checked_sub<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: Amount<C>,
fn checked_sub<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: Amount<C>,
Source§fn checked_mul<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
fn checked_mul<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
Source§fn checked_div<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
fn checked_div<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
Source§fn checked_rem<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
fn checked_rem<RHS>(&self, rhs: RHS) -> Option<Self>where
RHS: DecimalNumber,
Source§impl<'de, C: Currency> Deserialize<'de> for RawMoney<C>
impl<'de, C: Currency> Deserialize<'de> for RawMoney<C>
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
Source§impl<C> Display for RawMoney<C>where
C: Currency,
Formats RawMoney using the currency code and full decimal precision.
impl<C> Display for RawMoney<C>where
C: Currency,
Formats RawMoney using the currency code and full decimal precision.
§Examples
use moneylib::{RawMoney, macros::dec, iso::USD};
let raw = RawMoney::<USD>::from_decimal(dec!(1234.567));
assert_eq!(format!("{}", raw), "USD 1,234.567");
let raw = RawMoney::<USD>::from_decimal(dec!(-1234.56));
assert_eq!(format!("{}", raw), "USD -1,234.56");Source§impl<C> Div for RawMoney<C>where
C: Currency,
RawMoney / RawMoney = RawMoney (no auto-rounding)
impl<C> Div for RawMoney<C>where
C: Currency,
RawMoney / RawMoney = RawMoney (no auto-rounding)
Source§impl<C> DivAssign for RawMoney<C>where
C: Currency,
RawMoney /= RawMoney (no auto-rounding)
impl<C> DivAssign for RawMoney<C>where
C: Currency,
RawMoney /= RawMoney (no auto-rounding)
Source§fn div_assign(&mut self, other: Self)
fn div_assign(&mut self, other: Self)
/= operation. Read moreSource§impl<C> FromStr for RawMoney<C>where
C: Currency,
impl<C> FromStr for RawMoney<C>where
C: Currency,
Source§fn from_str(s: &str) -> Result<Self, Self::Err>
fn from_str(s: &str) -> Result<Self, Self::Err>
Parse money from string number.
§Examples
use moneylib::{BaseMoney, RawMoney, iso::USD, raw, dec};
use std::str::FromStr;
let money = RawMoney::<USD>::from_str("12334.4439").unwrap();
assert_eq!(money, raw!(USD, 12334.4439));
assert_eq!(money.amount(), dec!(12334.4439));Source§type Err = MoneyError
type Err = MoneyError
Source§impl<C> MoneyFormatter<C> for RawMoney<C>where
C: Currency,
impl<C> MoneyFormatter<C> for RawMoney<C>where
C: Currency,
Source§fn format(&self, format_str: &str) -> String
fn format(&self, format_str: &str) -> String
format_str. Read moreSource§fn format_with_separator(
&self,
format_str: &str,
thousand_separator: &str,
decimal_separator: &str,
) -> String
fn format_with_separator( &self, format_str: &str, thousand_separator: &str, decimal_separator: &str, ) -> String
format_str. Read moreSource§fn format_locale_amount(
&self,
locale_str: &str,
format_str: &str,
) -> Result<String, MoneyError>
fn format_locale_amount( &self, locale_str: &str, format_str: &str, ) -> Result<String, MoneyError>
format_str format. Read moreSource§impl<C> Mul for RawMoney<C>where
C: Currency,
RawMoney * RawMoney = RawMoney (no auto-rounding)
impl<C> Mul for RawMoney<C>where
C: Currency,
RawMoney * RawMoney = RawMoney (no auto-rounding)
Source§impl<C> MulAssign for RawMoney<C>where
C: Currency,
RawMoney *= RawMoney (no auto-rounding)
impl<C> MulAssign for RawMoney<C>where
C: Currency,
RawMoney *= RawMoney (no auto-rounding)
Source§fn mul_assign(&mut self, other: Self)
fn mul_assign(&mut self, other: Self)
*= operation. Read moreSource§impl<C: Currency + Copy + 'static + Send + Sync> ObjMoney for RawMoney<C>
impl<C: Currency + Copy + 'static + Send + Sync> ObjMoney for RawMoney<C>
Source§fn minor_unit(&self) -> u16
fn minor_unit(&self) -> u16
2 for USD).Source§fn thousand_separator(&self) -> &str
fn thousand_separator(&self) -> &str
"," for USD).Source§fn decimal_separator(&self) -> &str
fn decimal_separator(&self) -> &str
"." for USD).Source§fn minor_unit_symbol(&self) -> &str
fn minor_unit_symbol(&self) -> &str
"¢" for USD, "minor" when none is defined).Source§fn minor_amount(&self) -> Option<i128>
fn minor_amount(&self) -> Option<i128>
Source§fn convert(
&self,
to_code: &str,
rate: &dyn ObjRate,
) -> Result<Box<dyn ObjMoney>, MoneyError>
fn convert( &self, to_code: &str, rate: &dyn ObjRate, ) -> Result<Box<dyn ObjMoney>, MoneyError>
to_code with rateSource§fn is_positive(&self) -> bool
fn is_positive(&self) -> bool
true if the amount is positive. Read moreSource§fn is_negative(&self) -> bool
fn is_negative(&self) -> bool
true if the amount is negative. Read moreSource§fn format_code(&self) -> String
fn format_code(&self) -> String
"USD 1,234.56").Source§fn format_symbol(&self) -> String
fn format_symbol(&self) -> String
"$1,234.56").Source§fn format_code_minor(&self) -> String
fn format_code_minor(&self) -> String
"USD 123,456 ¢").Source§fn format_symbol_minor(&self) -> String
fn format_symbol_minor(&self) -> String
"$123,456 ¢").Source§impl<C> Ord for RawMoney<C>
impl<C> Ord for RawMoney<C>
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<C: PartialEq + Currency> PartialEq for RawMoney<C>
impl<C: PartialEq + Currency> PartialEq for RawMoney<C>
Source§impl<C> PartialOrd for RawMoney<C>
impl<C> PartialOrd for RawMoney<C>
Source§impl<C> Sub for RawMoney<C>where
C: Currency,
RawMoney - RawMoney = RawMoney (no auto-rounding)
impl<C> Sub for RawMoney<C>where
C: Currency,
RawMoney - RawMoney = RawMoney (no auto-rounding)
Source§impl<C> SubAssign for RawMoney<C>where
C: Currency,
RawMoney -= RawMoney (no auto-rounding)
impl<C> SubAssign for RawMoney<C>where
C: Currency,
RawMoney -= RawMoney (no auto-rounding)
Source§fn sub_assign(&mut self, other: Self)
fn sub_assign(&mut self, other: Self)
-= operation. Read moreSource§impl<C: Currency + Copy + 'static + Send + Sync> TryFrom<&dyn ObjMoney> for RawMoney<C>
Converts a reference to an ObjMoney trait object into RawMoney<C>.
impl<C: Currency + Copy + 'static + Send + Sync> TryFrom<&dyn ObjMoney> for RawMoney<C>
Converts a reference to an ObjMoney trait object into RawMoney<C>.
The conversion succeeds when the currency code of the trait object matches C::CODE.
The amount is stored without any rounding, preserving full decimal precision, exactly as
RawMoney::from_decimal does.
§Errors
Returns MoneyError::CurrencyMismatchError when the currency codes do not match.
§Examples
use moneylib::{RawMoney, ObjMoney, BaseMoney, MoneyError, macros::dec, iso::{USD, EUR}};
let obj: Box<dyn ObjMoney> = Box::new(RawMoney::<USD>::new(dec!(100.567)).unwrap());
// Successful conversion
let raw = RawMoney::<USD>::try_from(obj.as_ref()).unwrap();
assert_eq!(BaseMoney::amount(&raw), dec!(100.567));
assert_eq!(BaseMoney::code(&raw), "USD");
// Currency mismatch returns an error
assert!(RawMoney::<EUR>::try_from(obj.as_ref()).is_err());