levana_perpswap_cosmos/number/
nonzero.rs1use std::{
2 fmt::{Display, Formatter},
3 str::FromStr,
4};
5
6use anyhow::Context;
7use cosmwasm_std::Decimal256;
8
9use crate::prelude::Signed;
10
11use super::types::{NonZero, UnsignedDecimal};
12
13impl<T: UnsignedDecimal> NonZero<T> {
14 pub fn inverse(self) -> Self {
18 NonZero::new(T::from_decimal256(
19 Decimal256::one() / self.raw().into_decimal256(),
20 ))
21 .expect("NonZero::inverse failed but that should be impossible!")
22 }
23}
24
25impl<T: UnsignedDecimal> Display for NonZero<T> {
26 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
27 write!(f, "{}", self.raw())
28 }
29}
30
31impl<T: UnsignedDecimal> TryFrom<u128> for NonZero<T> {
32 type Error = anyhow::Error;
33
34 fn try_from(val: u128) -> Result<Self, Self::Error> {
35 Signed::<T>::from(val).try_into()
36 }
37}
38
39impl<T: UnsignedDecimal> TryFrom<u64> for NonZero<T> {
40 type Error = anyhow::Error;
41
42 fn try_from(val: u64) -> Result<Self, Self::Error> {
43 u128::from(val).try_into()
44 }
45}
46
47impl<T: UnsignedDecimal> TryFrom<&str> for NonZero<T> {
48 type Error = anyhow::Error;
49
50 fn try_from(value: &str) -> Result<Self, Self::Error> {
51 Self::from_str(value)
52 }
53}
54
55impl<T: UnsignedDecimal> FromStr for NonZero<T> {
56 type Err = anyhow::Error;
57
58 fn from_str(s: &str) -> Result<Self, Self::Err> {
59 Decimal256::from_str(s)
60 .ok()
61 .map(T::from_decimal256)
62 .and_then(NonZero::new)
63 .with_context(|| format!("Could not parse a non-zero value from: {s}"))
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use crate::prelude::{Number, NumberGtZero};
70
71 use quickcheck::quickcheck;
72
73 quickcheck! {
74 fn number_over_zero_roundtrip(num: u128) -> bool {
75 let number = (Number::from(num) + Number::ONE).unwrap();
76 let number_over_zero = NumberGtZero::try_from(number).unwrap();
77 let number2 = Number::from(number_over_zero);
78 assert_eq!(number, number2);
79 number == number2
80 }
81
82 fn negative_fails(num: u128) -> bool {
83 NumberGtZero::try_from(-Number::from(num)).unwrap_err();
84 true
85 }
86 }
87}