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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::{collections::BTreeMap, fmt::Display};

use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};

// TODO(xla): Document.
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
pub struct Asset {
    pub id: Id,
    pub denom: Denom,
}

// TODO(xla): Needs to get substantially more sophisticated to support stable and transparent use
// of ibc assets.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
pub struct Id(String);

impl Display for Id {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl TryFrom<&str> for Id {
    type Error = eyre::Report;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        Ok(Self(value.to_owned()))
    }
}

/// Denominiation of an asset.
// TODO(xla): Document.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
pub struct Denom {
    pub id: Id,
    pub base: String,
    pub units: Vec<Unit>,
}

// TODO(xla): Document.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
pub struct Unit {
    pub exponent: u8,
    pub denom: String,
}

pub struct Registry {
    assets: BTreeMap<Id, Asset>,
}

impl Registry {
    pub fn by_base_denom(&self, denom: &str) -> Option<&Asset> {
        self.assets
            .iter()
            .find(|(_, asset)| asset.denom.base == *denom)
            .map(|(_, asset)| asset)
    }
}

pub static REGISTRY: Lazy<Registry> = Lazy::new(|| {
    let id = Id::try_from("ugm").unwrap();
    let flt = Asset {
        id: id.clone(),
        denom: Denom {
            id: id.clone(),
            base: "ugm".to_owned(),
            units: vec![
                Unit {
                    exponent: 3,
                    denom: "mgm".to_owned(),
                },
                Unit {
                    exponent: 6,
                    denom: "gm".to_owned(),
                },
            ],
        },
    };

    let mut assets = BTreeMap::new();
    assets.insert(id, flt);

    Registry { assets }
});