use super::{define_signed_value_type, Error, ParamKind, Quantity, Volume};
define_signed_value_type!(
Price,
ParamKind::Price
);
impl Price {
pub fn calculate_volume(self, quantity: Quantity) -> Result<Volume, Error> {
let volume_decimal = self
.to_decimal()
.abs()
.checked_mul(quantity.to_decimal().abs())
.ok_or(Error::Overflow {
param: ParamKind::Price,
})?;
Volume::new(volume_decimal)
}
}
#[cfg(test)]
mod tests {
use super::Price;
use crate::param::{Error, ParamKind, Quantity};
use rust_decimal::Decimal;
fn d(value: &str) -> Decimal {
value
.parse()
.expect("decimal literal in tests must be valid")
}
#[test]
fn calculate_volume_works() {
let price = Price::from_str("42350.75").expect("must be valid");
let quantity = Quantity::from_str("0.15").expect("must be valid");
let volume = price
.calculate_volume(quantity)
.expect("volume must be calculable");
assert_eq!(volume.to_decimal(), d("6352.6125"));
}
#[test]
fn calculate_volume_reports_overflow_for_extreme_values() {
let price = Price::new(Decimal::MAX);
let quantity = Quantity::from_str("2").expect("must be valid");
assert_eq!(
price.calculate_volume(quantity),
Err(Error::Overflow {
param: ParamKind::Price
})
);
}
}