bitpanda_csv/trade/
asset.rs

1//! # Asset
2//!
3//! asset defintion
4
5use super::{CryptoCurrency, Currency};
6
7use std::fmt;
8
9mod metal;
10
11pub use metal::Metal;
12
13/// Defines the asset name. The asset can be a currency or an asset name (stock code)
14#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash)]
15#[serde(untagged)]
16pub enum Asset {
17    Currency(Currency),
18    Metal(Metal),
19    /// A symbol name
20    Ticker(String),
21    /// Hong kong stock identifier
22    HongKong(i64),
23}
24
25impl fmt::Display for Asset {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        let repr = (match self {
28            Self::Currency(Currency::Crypto(CryptoCurrency::OneInch)) => "1Inch".to_string(),
29            Self::Currency(Currency::Crypto(x)) => format!("{:?}", x),
30            Self::Currency(Currency::Fiat(x)) => format!("{:?}", x),
31            Self::Metal(metal) => metal.to_string(),
32            Self::Ticker(name) => name.to_string(),
33            Self::HongKong(num) => num.to_string(),
34        })
35        .to_uppercase();
36        write!(f, "{}", repr)
37    }
38}
39
40#[cfg(test)]
41mod test {
42
43    use super::*;
44    use crate::{CryptoCurrency, Fiat};
45
46    use pretty_assertions::assert_eq;
47    use std::io::Cursor;
48
49    #[test]
50    fn should_convert_asset_to_string() {
51        assert_eq!(
52            Asset::Ticker(String::from("AMZN")).to_string().as_str(),
53            "AMZN"
54        );
55        assert_eq!(Asset::HongKong(1197).to_string().as_str(), "1197");
56        assert_eq!(
57            Asset::Currency(Currency::Fiat(Fiat::Eur))
58                .to_string()
59                .as_str(),
60            "EUR"
61        );
62        assert_eq!(
63            Asset::Currency(Currency::Crypto(CryptoCurrency::Btc))
64                .to_string()
65                .as_str(),
66            "BTC"
67        );
68        assert_eq!(
69            Asset::Currency(Currency::Crypto(CryptoCurrency::OneInch))
70                .to_string()
71                .as_str(),
72            "1INCH"
73        );
74        assert_eq!(Asset::Metal(Metal::Gold).to_string().as_str(), "XAU");
75        assert_eq!(Asset::Metal(Metal::Silver).to_string().as_str(), "XAG");
76        assert_eq!(Asset::Metal(Metal::Palladium).to_string().as_str(), "XPD");
77        assert_eq!(Asset::Metal(Metal::Platinum).to_string().as_str(), "XPT");
78    }
79
80    #[test]
81    fn should_decode_asset() {
82        let csv = r#"id,asset
830,EUR
841,BTC
852,TSLA
863,Gold
874,1177
88"#;
89        let buffer = Cursor::new(csv);
90        let mut reader = csv::Reader::from_reader(buffer);
91        let mut fakes: Vec<Asset> = Vec::new();
92        for result in reader.deserialize::<Fake>() {
93            fakes.push(result.expect("failed to decode").asset);
94        }
95        assert_eq!(
96            fakes,
97            vec![
98                Asset::Currency(Currency::Fiat(Fiat::Eur)),
99                Asset::Currency(Currency::Crypto(CryptoCurrency::Btc)),
100                Asset::Ticker("TSLA".to_string()),
101                Asset::Metal(Metal::Gold),
102                Asset::HongKong(1177),
103            ]
104        );
105    }
106
107    #[derive(Deserialize)]
108    #[allow(dead_code)]
109    struct Fake {
110        id: u64,
111        asset: Asset,
112    }
113}