1use std::{fmt, num::ParseIntError, str::FromStr};
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use super::error::ChainError;
7
8#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq, Hash)]
9pub struct Coin {
10 pub denom: Denom,
11 pub amount: u128,
12}
13
14impl fmt::Display for Coin {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(f, "{}{}", self.amount, self.denom)
17 }
18}
19
20impl TryFrom<Coin> for cosmrs::Coin {
21 type Error = ChainError;
22
23 fn try_from(coin: Coin) -> Result<Self, Self::Error> {
24 Ok(Self {
25 denom: coin.denom.try_into()?,
26 amount: coin.amount,
27 })
28 }
29}
30
31impl TryFrom<cosmrs::Coin> for Coin {
32 type Error = ChainError;
33
34 fn try_from(coin: cosmrs::Coin) -> Result<Self, Self::Error> {
35 Ok(Self {
36 denom: coin.denom.try_into()?,
37 amount: coin.amount,
38 })
39 }
40}
41
42impl TryFrom<cosmrs::proto::cosmos::base::v1beta1::Coin> for Coin {
43 type Error = ChainError;
44
45 fn try_from(coin: cosmrs::proto::cosmos::base::v1beta1::Coin) -> Result<Self, Self::Error> {
46 Ok(Self {
47 denom: coin.denom.parse()?,
48 amount: coin
49 .amount
50 .parse()
51 .map_err(|e: ParseIntError| ChainError::ProtoDecoding {
52 message: e.to_string(),
53 })?,
54 })
55 }
56}
57
58impl From<Coin> for cosmrs::proto::cosmos::base::v1beta1::Coin {
59 fn from(coin: Coin) -> Self {
60 Self {
61 denom: coin.denom.into(),
62 amount: coin.amount.to_string(),
63 }
64 }
65}
66
67#[derive(
68 Clone, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq, PartialOrd, Ord, Hash,
69)]
70pub struct Denom(String);
71
72impl AsRef<str> for Denom {
73 fn as_ref(&self) -> &str {
74 self.0.as_ref()
75 }
76}
77
78impl fmt::Display for Denom {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 f.write_str(self.as_ref())
81 }
82}
83
84impl FromStr for Denom {
85 type Err = ChainError;
86
87 fn from_str(s: &str) -> Result<Self, Self::Err> {
88 Ok(Denom(s.to_owned()))
89 }
90}
91
92impl TryFrom<cosmrs::Denom> for Denom {
93 type Error = ChainError;
94
95 fn try_from(d: cosmrs::Denom) -> Result<Self, Self::Error> {
96 d.as_ref().parse()
97 }
98}
99
100impl TryFrom<Denom> for cosmrs::Denom {
101 type Error = ChainError;
102
103 fn try_from(d: Denom) -> Result<Self, Self::Error> {
104 d.0.parse().map_err(|_| ChainError::Denom { name: d.0 })
105 }
106}
107
108impl From<Denom> for String {
109 fn from(d: Denom) -> Self {
110 d.0
111 }
112}