@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
4
4
use std:: fmt;
5
5
6
6
/// Coin defines a token with a denomination and an amount.
7
- #[ derive( Serialize , Deserialize , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
7
+ #[ derive( Clone , Debug , Default , Eq , PartialEq , PartialOrd , Ord , Serialize , Deserialize ) ]
8
8
pub struct Coin {
9
9
/// Denomination
10
10
pub denom : Denom ,
@@ -35,10 +35,15 @@ impl TryFrom<&proto::cosmos::base::v1beta1::Coin> for Coin {
35
35
type Error = ErrorReport ;
36
36
37
37
fn try_from ( proto : & proto:: cosmos:: base:: v1beta1:: Coin ) -> Result < Coin > {
38
- Ok ( Coin {
39
- denom : proto. denom . parse ( ) ?,
40
- amount : proto. amount . parse ( ) ?,
41
- } )
38
+ // Support an empty denom when the amount is `0`. See cosmos/cosmos-rust#477
39
+ if proto. denom . is_empty ( ) && proto. amount == "0" {
40
+ Ok ( Coin :: default ( ) )
41
+ } else {
42
+ Ok ( Coin {
43
+ denom : proto. denom . parse ( ) ?,
44
+ amount : proto. amount . parse ( ) ?,
45
+ } )
46
+ }
42
47
}
43
48
}
44
49
@@ -67,9 +72,20 @@ impl fmt::Display for Coin {
67
72
#[ cfg( test) ]
68
73
mod tests {
69
74
use super :: Coin ;
75
+ use crate :: proto;
70
76
71
77
#[ test]
72
78
fn new ( ) {
73
79
Coin :: new ( 1000 , "uatom" ) . unwrap ( ) ;
74
80
}
81
+
82
+ #[ test]
83
+ fn zero_value_coin_with_empty_denom ( ) {
84
+ let zero_proto = proto:: cosmos:: base:: v1beta1:: Coin :: from ( Coin :: default ( ) ) ;
85
+ assert_eq ! ( & zero_proto. denom, "" ) ;
86
+ assert_eq ! ( & zero_proto. amount, "0" ) ;
87
+
88
+ let zero_coin = Coin :: try_from ( zero_proto) . unwrap ( ) ;
89
+ assert_eq ! ( zero_coin, Coin :: default ( ) )
90
+ }
75
91
}
0 commit comments