units: Move general result stuff to a separate module
We currently use the `NumOpResult` for operations involving more than just amount types (e.g. `FeeRate`) however when the `result` module was written we only used amount types. To make the intention of the custom result types more clear introduce a top level `result` module and move the general code there. Leave the amount implementations in the `amount` module. Note that both `result` modules are private. Move the `OptionExt` impls because later we will add a bunch more of them. Internal change only, no logic changes.
This commit is contained in:
parent
f49efdf3f7
commit
f5b54e5fe0
|
@ -35,11 +35,9 @@ pub use self::{
|
||||||
OutOfRangeError, ParseAmountError, ParseDenominationError, ParseError,
|
OutOfRangeError, ParseAmountError, ParseDenominationError, ParseError,
|
||||||
PossiblyConfusingDenominationError, TooPreciseError, UnknownDenominationError,
|
PossiblyConfusingDenominationError, TooPreciseError, UnknownDenominationError,
|
||||||
},
|
},
|
||||||
result::{NumOpError, NumOpResult},
|
|
||||||
signed::SignedAmount,
|
signed::SignedAmount,
|
||||||
unsigned::Amount,
|
unsigned::Amount,
|
||||||
};
|
};
|
||||||
pub(crate) use self::result::OptionExt;
|
|
||||||
|
|
||||||
/// A set of denominations in which amounts can be expressed.
|
/// A set of denominations in which amounts can be expressed.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2,109 +2,12 @@
|
||||||
|
|
||||||
//! Provides a monodic type returned by mathematical operations (`core::ops`).
|
//! Provides a monodic type returned by mathematical operations (`core::ops`).
|
||||||
|
|
||||||
use core::{fmt, ops};
|
use core::ops;
|
||||||
|
|
||||||
use NumOpResult as R;
|
use NumOpResult as R;
|
||||||
|
|
||||||
use super::{Amount, SignedAmount};
|
use super::{Amount, SignedAmount};
|
||||||
|
use crate::{NumOpError, NumOpResult, OptionExt};
|
||||||
/// Result of a mathematical operation on two numeric types.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
#[must_use]
|
|
||||||
pub enum NumOpResult<T> {
|
|
||||||
/// Result of a successful mathematical operation.
|
|
||||||
Valid(T),
|
|
||||||
/// Result of an unsuccessful mathematical operation.
|
|
||||||
Error(NumOpError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: fmt::Debug> NumOpResult<T> {
|
|
||||||
/// Returns the contained valid numeric type, consuming `self`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics with `msg` if the numeric result is an `Error`.
|
|
||||||
#[inline]
|
|
||||||
#[track_caller]
|
|
||||||
pub fn expect(self, msg: &str) -> T {
|
|
||||||
match self {
|
|
||||||
R::Valid(x) => x,
|
|
||||||
R::Error(_) => panic!("{}", msg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the contained valid numeric type, consuming `self`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the numeric result is an `Error`.
|
|
||||||
#[inline]
|
|
||||||
#[track_caller]
|
|
||||||
pub fn unwrap(self) -> T {
|
|
||||||
match self {
|
|
||||||
R::Valid(x) => x,
|
|
||||||
R::Error(e) => panic!("tried to unwrap an invalid numeric result: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the contained error, consuming `self`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the numeric result is valid.
|
|
||||||
#[inline]
|
|
||||||
#[track_caller]
|
|
||||||
pub fn unwrap_err(self) -> NumOpError {
|
|
||||||
match self {
|
|
||||||
R::Error(e) => e,
|
|
||||||
R::Valid(a) => panic!("tried to unwrap a valid numeric result: {:?}", a),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts this `NumOpResult` to an `Option<T>`.
|
|
||||||
#[inline]
|
|
||||||
pub fn ok(self) -> Option<T> {
|
|
||||||
match self {
|
|
||||||
R::Valid(x) => Some(x),
|
|
||||||
R::Error(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts this `NumOpResult` to a `Result<T, NumOpError>`.
|
|
||||||
#[inline]
|
|
||||||
#[allow(clippy::missing_errors_doc)]
|
|
||||||
pub fn into_result(self) -> Result<T, NumOpError> {
|
|
||||||
match self {
|
|
||||||
R::Valid(x) => Ok(x),
|
|
||||||
R::Error(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calls `op` if the numeric result is `Valid`, otherwise returns the `Error` value of `self`.
|
|
||||||
#[inline]
|
|
||||||
pub fn and_then<F>(self, op: F) -> NumOpResult<T>
|
|
||||||
where
|
|
||||||
F: FnOnce(T) -> NumOpResult<T>,
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
R::Valid(x) => op(x),
|
|
||||||
R::Error(e) => R::Error(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if the numeric result is valid.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_valid(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
R::Valid(_) => true,
|
|
||||||
R::Error(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if the numeric result is invalid.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_error(&self) -> bool { !self.is_valid() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Amount> for NumOpResult<Amount> {
|
impl From<Amount> for NumOpResult<Amount> {
|
||||||
fn from(a: Amount) -> Self { Self::Valid(a) }
|
fn from(a: Amount) -> Self { Self::Valid(a) }
|
||||||
|
@ -376,41 +279,3 @@ impl<'a> core::iter::Sum<&'a NumOpResult<SignedAmount>> for NumOpResult<SignedAm
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait OptionExt<T> {
|
|
||||||
fn valid_or_error(self) -> NumOpResult<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OptionExt<Amount> for Option<Amount> {
|
|
||||||
#[inline]
|
|
||||||
fn valid_or_error(self) -> NumOpResult<Amount> {
|
|
||||||
match self {
|
|
||||||
Some(amount) => R::Valid(amount),
|
|
||||||
None => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OptionExt<SignedAmount> for Option<SignedAmount> {
|
|
||||||
#[inline]
|
|
||||||
fn valid_or_error(self) -> NumOpResult<SignedAmount> {
|
|
||||||
match self {
|
|
||||||
Some(amount) => R::Valid(amount),
|
|
||||||
None => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error occurred while doing a mathematical operation.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub struct NumOpError;
|
|
||||||
|
|
||||||
impl fmt::Display for NumOpError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "a math operation gave an invalid numeric result")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl std::error::Error for NumOpError {}
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ use std::panic;
|
||||||
use ::serde::{Deserialize, Serialize};
|
use ::serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::NumOpResult;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use crate::{FeeRate, Weight};
|
use crate::{FeeRate, Weight};
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
|
|
||||||
use core::ops;
|
use core::ops;
|
||||||
|
|
||||||
use crate::amount::{NumOpResult, OptionExt};
|
use crate::{Amount, FeeRate, NumOpResult, OptionExt, Weight};
|
||||||
use crate::{Amount, FeeRate, Weight};
|
|
||||||
|
|
||||||
impl Amount {
|
impl Amount {
|
||||||
/// Checked weight ceiling division.
|
/// Checked weight ceiling division.
|
||||||
|
|
|
@ -20,6 +20,7 @@ extern crate std;
|
||||||
|
|
||||||
mod fee;
|
mod fee;
|
||||||
mod internal_macros;
|
mod internal_macros;
|
||||||
|
mod result;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod _export {
|
pub mod _export {
|
||||||
|
@ -43,6 +44,8 @@ pub use self::{
|
||||||
amount::{Amount, SignedAmount},
|
amount::{Amount, SignedAmount},
|
||||||
block::{BlockHeight, BlockInterval},
|
block::{BlockHeight, BlockInterval},
|
||||||
fee_rate::FeeRate,
|
fee_rate::FeeRate,
|
||||||
|
result::{NumOpError, NumOpResult},
|
||||||
time::BlockTime,
|
time::BlockTime,
|
||||||
weight::Weight
|
weight::Weight
|
||||||
};
|
};
|
||||||
|
pub(crate) use self::result::OptionExt;
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
//! Provides a monodic type returned by mathematical operations (`core::ops`).
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use NumOpResult as R;
|
||||||
|
|
||||||
|
use crate::{Amount, SignedAmount};
|
||||||
|
|
||||||
|
/// Result of a mathematical operation on two numeric types.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[must_use]
|
||||||
|
pub enum NumOpResult<T> {
|
||||||
|
/// Result of a successful mathematical operation.
|
||||||
|
Valid(T),
|
||||||
|
/// Result of an unsuccessful mathematical operation.
|
||||||
|
Error(NumOpError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Debug> NumOpResult<T> {
|
||||||
|
/// Returns the contained valid numeric type, consuming `self`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics with `msg` if the numeric result is an `Error`.
|
||||||
|
#[inline]
|
||||||
|
#[track_caller]
|
||||||
|
pub fn expect(self, msg: &str) -> T {
|
||||||
|
match self {
|
||||||
|
R::Valid(x) => x,
|
||||||
|
R::Error(_) => panic!("{}", msg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the contained valid numeric type, consuming `self`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the numeric result is an `Error`.
|
||||||
|
#[inline]
|
||||||
|
#[track_caller]
|
||||||
|
pub fn unwrap(self) -> T {
|
||||||
|
match self {
|
||||||
|
R::Valid(x) => x,
|
||||||
|
R::Error(e) => panic!("tried to unwrap an invalid numeric result: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the contained error, consuming `self`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the numeric result is valid.
|
||||||
|
#[inline]
|
||||||
|
#[track_caller]
|
||||||
|
pub fn unwrap_err(self) -> NumOpError {
|
||||||
|
match self {
|
||||||
|
R::Error(e) => e,
|
||||||
|
R::Valid(a) => panic!("tried to unwrap a valid numeric result: {:?}", a),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts this `NumOpResult` to an `Option<T>`.
|
||||||
|
#[inline]
|
||||||
|
pub fn ok(self) -> Option<T> {
|
||||||
|
match self {
|
||||||
|
R::Valid(x) => Some(x),
|
||||||
|
R::Error(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts this `NumOpResult` to a `Result<T, NumOpError>`.
|
||||||
|
#[inline]
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
|
pub fn into_result(self) -> Result<T, NumOpError> {
|
||||||
|
match self {
|
||||||
|
R::Valid(x) => Ok(x),
|
||||||
|
R::Error(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calls `op` if the numeric result is `Valid`, otherwise returns the `Error` value of `self`.
|
||||||
|
#[inline]
|
||||||
|
pub fn and_then<F>(self, op: F) -> NumOpResult<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(T) -> NumOpResult<T>,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
R::Valid(x) => op(x),
|
||||||
|
R::Error(e) => R::Error(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the numeric result is valid.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
R::Valid(_) => true,
|
||||||
|
R::Error(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the numeric result is invalid.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_error(&self) -> bool { !self.is_valid() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) trait OptionExt<T> {
|
||||||
|
fn valid_or_error(self) -> NumOpResult<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OptionExt<Amount> for Option<Amount> {
|
||||||
|
#[inline]
|
||||||
|
fn valid_or_error(self) -> NumOpResult<Amount> {
|
||||||
|
match self {
|
||||||
|
Some(amount) => R::Valid(amount),
|
||||||
|
None => R::Error(NumOpError {}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OptionExt<SignedAmount> for Option<SignedAmount> {
|
||||||
|
#[inline]
|
||||||
|
fn valid_or_error(self) -> NumOpResult<SignedAmount> {
|
||||||
|
match self {
|
||||||
|
Some(amount) => R::Valid(amount),
|
||||||
|
None => R::Error(NumOpError {}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error occurred while doing a mathematical operation.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct NumOpError;
|
||||||
|
|
||||||
|
impl fmt::Display for NumOpError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "a math operation gave an invalid numeric result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl std::error::Error for NumOpError {}
|
Loading…
Reference in New Issue