Skip to content

Commit b44dae5

Browse files
committed
Decimal/Decimal256: Refactor checked_from_ratio implementation to use its own error type
1 parent e604447 commit b44dae5

File tree

5 files changed

+54
-26
lines changed

5 files changed

+54
-26
lines changed

packages/std/src/errors/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ mod verification_error;
55

66
pub use recover_pubkey_error::RecoverPubkeyError;
77
pub use std_error::{
8-
CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError, OverflowError,
9-
OverflowOperation, StdError, StdResult,
8+
CheckedFromRatioError, CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError,
9+
OverflowError, OverflowOperation, StdError, StdResult,
1010
};
1111
pub use system_error::SystemError;
1212
pub use verification_error::VerificationError;

packages/std/src/errors/std_error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,15 @@ pub enum CheckedMultiplyRatioError {
535535
Overflow,
536536
}
537537

538+
#[derive(Error, Debug, PartialEq, Eq)]
539+
pub enum CheckedFromRatioError {
540+
#[error("Denominator must not be zero")]
541+
DivideByZero,
542+
543+
#[error("Multiplication overflow")]
544+
MulOverflow,
545+
}
546+
538547
#[cfg(test)]
539548
mod tests {
540549
use super::*;

packages/std/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ pub use crate::binary::Binary;
2828
pub use crate::coins::{coin, coins, has_coins, Coin};
2929
pub use crate::deps::{Deps, DepsMut, OwnedDeps};
3030
pub use crate::errors::{
31-
CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError, OverflowError,
32-
OverflowOperation, RecoverPubkeyError, StdError, StdResult, SystemError, VerificationError,
31+
CheckedFromRatioError, CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError,
32+
OverflowError, OverflowOperation, RecoverPubkeyError, StdError, StdResult, SystemError,
33+
VerificationError,
3334
};
3435
#[cfg(feature = "stargate")]
3536
pub use crate::ibc::{

packages/std/src/math/decimal.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
77
use std::str::FromStr;
88
use thiserror::Error;
99

10-
use crate::errors::{CheckedMultiplyRatioError, StdError};
10+
use crate::errors::{CheckedFromRatioError, StdError};
1111
use crate::OverflowError;
1212

1313
use super::Fraction;
@@ -120,28 +120,31 @@ impl Decimal {
120120
pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
121121
match Decimal::checked_from_ratio(numerator, denominator) {
122122
Ok(value) => value,
123-
Err(CheckedMultiplyRatioError::DivideByZero) => {
123+
Err(CheckedFromRatioError::DivideByZero) => {
124124
panic!("Denominator must not be zero")
125125
}
126-
Err(CheckedMultiplyRatioError::Overflow) => panic!("Multiplication overflow"),
126+
Err(CheckedFromRatioError::MulOverflow) => panic!("Multiplication overflow"),
127127
}
128128
}
129129

130130
/// Returns the ratio (numerator / denominator) as a Decimal
131131
pub fn checked_from_ratio(
132132
numerator: impl Into<Uint128>,
133133
denominator: impl Into<Uint128>,
134-
) -> Result<Self, CheckedMultiplyRatioError> {
134+
) -> Result<Self, CheckedFromRatioError> {
135135
let numerator: Uint128 = numerator.into();
136136
let denominator: Uint128 = denominator.into();
137137
if denominator.is_zero() {
138-
return Err(CheckedMultiplyRatioError::DivideByZero);
138+
return Err(CheckedFromRatioError::DivideByZero);
139139
}
140140

141-
Ok(Decimal(
142-
// numerator * DECIMAL_FRACTIONAL / denominator
143-
numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator)?,
144-
))
141+
match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
142+
Ok(ratio) => {
143+
// numerator * DECIMAL_FRACTIONAL / denominator
144+
Ok(Decimal(ratio))
145+
}
146+
Err(_) => Err(CheckedFromRatioError::MulOverflow),
147+
}
145148
}
146149

147150
pub const fn is_zero(&self) -> bool {
@@ -672,16 +675,22 @@ mod tests {
672675
Decimal::from_ratio(1u128, 0u128);
673676
}
674677

678+
#[test]
679+
#[should_panic(expected = "Multiplication overflow")]
680+
fn decimal_from_ratio_panics_for_mul_overflow() {
681+
Decimal::from_ratio(u128::MAX, 1u128);
682+
}
683+
675684
#[test]
676685
fn decimal_checked_from_ratio_does_not_panic() {
677686
assert_eq!(
678687
Decimal::checked_from_ratio(1u128, 0u128),
679-
Err(CheckedMultiplyRatioError::DivideByZero)
688+
Err(CheckedFromRatioError::DivideByZero)
680689
);
681690

682691
assert_eq!(
683692
Decimal::checked_from_ratio(u128::MAX, 1u128),
684-
Err(CheckedMultiplyRatioError::Overflow)
693+
Err(CheckedFromRatioError::MulOverflow)
685694
);
686695
}
687696

packages/std/src/math/decimal256.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
77
use std::str::FromStr;
88
use thiserror::Error;
99

10-
use crate::errors::{CheckedMultiplyRatioError, StdError};
10+
use crate::errors::{CheckedFromRatioError, StdError};
1111
use crate::{OverflowError, Uint512};
1212

1313
use super::Fraction;
@@ -132,28 +132,31 @@ impl Decimal256 {
132132
pub fn from_ratio(numerator: impl Into<Uint256>, denominator: impl Into<Uint256>) -> Self {
133133
match Decimal256::checked_from_ratio(numerator, denominator) {
134134
Ok(value) => value,
135-
Err(CheckedMultiplyRatioError::DivideByZero) => {
135+
Err(CheckedFromRatioError::DivideByZero) => {
136136
panic!("Denominator must not be zero")
137137
}
138-
Err(CheckedMultiplyRatioError::Overflow) => panic!("Multiplication overflow"),
138+
Err(CheckedFromRatioError::MulOverflow) => panic!("Multiplication overflow"),
139139
}
140140
}
141141

142142
/// Returns the ratio (numerator / denominator) as a Decimal256
143143
pub fn checked_from_ratio(
144144
numerator: impl Into<Uint256>,
145145
denominator: impl Into<Uint256>,
146-
) -> Result<Self, CheckedMultiplyRatioError> {
146+
) -> Result<Self, CheckedFromRatioError> {
147147
let numerator: Uint256 = numerator.into();
148148
let denominator: Uint256 = denominator.into();
149149
if denominator.is_zero() {
150-
return Err(CheckedMultiplyRatioError::DivideByZero);
150+
return Err(CheckedFromRatioError::DivideByZero);
151151
}
152152

153-
Ok(Self(
154-
// numerator * DECIMAL_FRACTIONAL / denominator
155-
numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator)?,
156-
))
153+
match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
154+
Ok(ratio) => {
155+
// numerator * DECIMAL_FRACTIONAL / denominator
156+
Ok(Self(ratio))
157+
}
158+
Err(_) => Err(CheckedFromRatioError::MulOverflow),
159+
}
157160
}
158161

159162
pub const fn is_zero(&self) -> bool {
@@ -704,16 +707,22 @@ mod tests {
704707
Decimal256::from_ratio(1u128, 0u128);
705708
}
706709

710+
#[test]
711+
#[should_panic(expected = "Multiplication overflow")]
712+
fn decimal256_from_ratio_panics_for_mul_overflow() {
713+
Decimal256::from_ratio(Uint256::MAX, 1u128);
714+
}
715+
707716
#[test]
708717
fn decimal256_checked_from_ratio_does_not_panic() {
709718
assert_eq!(
710719
Decimal256::checked_from_ratio(1u128, 0u128),
711-
Err(CheckedMultiplyRatioError::DivideByZero)
720+
Err(CheckedFromRatioError::DivideByZero)
712721
);
713722

714723
assert_eq!(
715724
Decimal256::checked_from_ratio(Uint256::MAX, 1u128),
716-
Err(CheckedMultiplyRatioError::Overflow)
725+
Err(CheckedFromRatioError::MulOverflow)
717726
);
718727
}
719728

0 commit comments

Comments
 (0)