1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Types of values that can be present in an `sdk.Msg`

use crate::Error;
use eyre::{Result, WrapErr};
use serde::{de, Deserialize};
use std::{
    fmt::{self, Display},
    str::FromStr,
};

/// Types of Amino values which can be included in a [`sdk.Msg`]
///
/// [`sdk.Msg`]: https://godoc.org/github.com/cosmos/cosmos-sdk/types#Msg
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ValueType {
    /// Bytes
    Bytes,

    /// `sdk.AccAddress`: Cosmos SDK account addresses
    /// <https://godoc.org/github.com/cosmos/cosmos-sdk/types#AccAddress>
    SdkAccAddress,

    /// `sdk.Dec`: Cosmos SDK decimals
    /// <https://godoc.org/github.com/cosmos/cosmos-sdk/types#Dec>
    SdkDecimal,

    /// `sdk.ValAddress`: Cosmos SDK validator addresses
    /// <https://godoc.org/github.com/cosmos/cosmos-sdk/types#ValAddress>
    SdkValAddress,

    /// Strings
    String,
}

impl Display for ValueType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            ValueType::Bytes => "bytes",
            ValueType::SdkAccAddress => "sdk.AccAddress",
            ValueType::SdkDecimal => "sdk.Dec",
            ValueType::SdkValAddress => "sdk.ValAddress",
            ValueType::String => "string",
        })
    }
}

impl FromStr for ValueType {
    type Err = eyre::Report;

    fn from_str(s: &str) -> Result<Self> {
        match s {
            "bytes" => Ok(ValueType::Bytes),
            "sdk.AccAddress" => Ok(ValueType::SdkAccAddress),
            "sdk.Dec" => Ok(ValueType::SdkDecimal),
            "sdk.ValAddress" => Ok(ValueType::SdkValAddress),
            "string" => Ok(ValueType::String),
            _ => Err(Error::Parse).wrap_err_with(|| format!("unknown value type: `{}`", s)),
        }
    }
}

impl<'de> Deserialize<'de> for ValueType {
    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        use de::Error;
        let s = String::deserialize(deserializer)?;
        s.parse().map_err(D::Error::custom)
    }
}