more_fps/
non_zero_decimal.rs1use rust_decimal::Decimal;
2
3#[derive(Debug, PartialEq, Clone, Copy)]
4pub struct NonZeroDecimal(Decimal);
5
6impl NonZeroDecimal {
7 pub fn try_new<T>(value: T) -> Option<Self>
8 where
9 T: TryInto<Decimal>,
10 {
11 let value = value.try_into().ok()?;
12 if value == Decimal::ZERO {
13 None
14 } else {
15 Some(Self(value))
16 }
17 }
18
19 pub fn get(&self) -> &Decimal {
20 &self.0
21 }
22}
23
24impl std::ops::Deref for NonZeroDecimal {
25 type Target = Decimal;
26 fn deref(&self) -> &Self::Target {
27 &self.0
28 }
29}
30
31impl TryFrom<&str> for NonZeroDecimal {
32 type Error = rust_decimal::Error;
33 fn try_from(s: &str) -> Result<Self, Self::Error> {
34 let decimal = Decimal::from_str_exact(s)?;
35 Ok(Self(decimal))
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn non_zero_decimal() {
45 assert_eq!(
46 NonZeroDecimal::try_new(12).map(|d| d.get().clone()),
47 Some(Decimal::from_str_exact("12").unwrap())
48 );
49 }
50 #[test]
51 fn zero_decimal() {
52 assert_eq!(NonZeroDecimal::try_new(0), None);
53 }
54}