Skip to content

Commit

Permalink
Merge pull request #19 from invariant-labs/add-checked_big_div
Browse files Browse the repository at this point in the history
Add checked big div
  • Loading branch information
wojciech-cichocki authored Oct 11, 2023
2 parents 9d4992b + 39bd3d2 commit 0755759
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
29 changes: 29 additions & 0 deletions decimal_core/src/big_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ pub fn generate_big_ops(characteristics: DecimalCharacteristics) -> proc_macro::
)
}

fn checked_big_div(self, rhs: T) -> std::result::Result<Self, String> {
Ok(
Self::new(
#big_type::try_from(self.get())
.map_err(|_| format!("decimal: lhs value can't fit into `{}` type in {}::big_div()", #big_str, #name_str))?
.checked_mul(
T::one()
)
.ok_or_else(|| format!("decimal: overflow in method {}::big_div()", #name_str))?
.checked_div(
rhs.get()
.try_into()
.map_err(|_| format!("decimal: rhs value can't fit into `{}` type in {}::big_div()", #big_str, #name_str))?
)
.ok_or_else(|| format!("decimal: overflow in method {}::big_div()", #name_str))?
.try_into()
.map_err(|_| format!("decimal: overflow casting result to `{}` type in method {}::big_div()", #underlying_str, #name_str))?
)
)
}

fn big_div_up(self, rhs: T) -> Self {
Self::new(
#big_type::try_from(self.get())
Expand Down Expand Up @@ -133,6 +154,14 @@ pub fn generate_big_ops(characteristics: DecimalCharacteristics) -> proc_macro::
assert_eq!(a.big_div(b), #struct_name::new(2));
}


#[test]
fn test_checked_big_div () {
let a = #struct_name::new(29);
let b = #struct_name::new(#struct_name::one());
assert_eq!(a.big_div(b), #struct_name::new(29));
}

#[test]
fn test_big_div_up () {
let a = #struct_name::new(2);
Expand Down
3 changes: 2 additions & 1 deletion src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ pub trait Decimal {
fn almost_one<T: TryFrom<u128>>() -> T;
}

pub trait BigOps<T> {
pub trait BigOps<T>: Sized {
fn big_mul(self, rhs: T) -> Self;
fn big_mul_up(self, rhs: T) -> Self;
fn big_div(self, rhs: T) -> Self;
fn checked_big_div(self, rhs: T) -> std::result::Result<Self, String>;
fn big_div_up(self, rhs: T) -> Self;
}

Expand Down
5 changes: 5 additions & 0 deletions src/walkthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ mod walkthrough {
let result = percentage.checked_sub(Percentage::new(10));
assert_eq!(result, Ok(Percentage::new(90)));
}
// checked big div
{
let price = Price::max_instance().checked_big_div(Price::new(50000));
assert_eq!(price, Ok(Price::new(68056473384187692692674921486353642291)));
}

// checked_from_scale
{
Expand Down

0 comments on commit 0755759

Please sign in to comment.