waves_rust/model/transaction/
burn_transaction.rs

1use crate::error::{Error, Result};
2use crate::model::{Amount, AssetId, ByteString};
3use crate::util::JsonDeserializer;
4use crate::waves_proto::{Amount as ProtoAmount, BurnTransactionData};
5use serde_json::{Map, Value};
6
7const TYPE: u8 = 6;
8
9#[derive(Clone, Eq, PartialEq, Debug)]
10pub struct BurnTransactionInfo {
11    amount: Amount,
12}
13
14impl BurnTransactionInfo {
15    pub fn new(amount: Amount) -> Self {
16        Self { amount }
17    }
18
19    pub fn amount(&self) -> Amount {
20        self.amount.clone()
21    }
22}
23
24impl TryFrom<&Value> for BurnTransactionInfo {
25    type Error = Error;
26
27    fn try_from(value: &Value) -> Result<Self> {
28        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
29        let asset_id = match value["assetId"].as_str() {
30            Some(asset) => Some(AssetId::from_string(asset)?),
31            None => None,
32        };
33
34        Ok(BurnTransactionInfo {
35            amount: Amount::new(amount as u64, asset_id),
36        })
37    }
38}
39
40#[derive(Clone, Eq, PartialEq, Debug)]
41pub struct BurnTransaction {
42    amount: Amount,
43}
44
45impl BurnTransaction {
46    pub fn new(amount: Amount) -> Self {
47        Self { amount }
48    }
49
50    pub fn tx_type() -> u8 {
51        TYPE
52    }
53
54    pub fn amount(&self) -> Amount {
55        self.amount.clone()
56    }
57}
58
59impl TryFrom<&Value> for BurnTransaction {
60    type Error = Error;
61
62    fn try_from(value: &Value) -> Result<Self> {
63        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
64        let asset_id = match value["assetId"].as_str() {
65            Some(asset) => Some(AssetId::from_string(asset)?),
66            None => None,
67        };
68
69        Ok(BurnTransaction {
70            amount: Amount::new(amount as u64, asset_id),
71        })
72    }
73}
74
75impl TryFrom<&BurnTransaction> for Map<String, Value> {
76    type Error = Error;
77
78    fn try_from(value: &BurnTransaction) -> Result<Self> {
79        let mut issue_tx_json = Map::new();
80        issue_tx_json.insert(
81            "assetId".to_owned(),
82            value
83                .amount
84                .asset_id()
85                .map(|asset| asset.encoded().into())
86                .unwrap_or(Value::Null),
87        );
88        issue_tx_json.insert("amount".to_owned(), value.amount.value().into());
89        Ok(issue_tx_json)
90    }
91}
92
93impl TryFrom<&BurnTransaction> for BurnTransactionData {
94    type Error = Error;
95
96    fn try_from(value: &BurnTransaction) -> Result<Self> {
97        let asset_id = match value.amount.asset_id() {
98            Some(asset) => asset.bytes(),
99            None => vec![],
100        };
101        let amount = Some(ProtoAmount {
102            asset_id,
103            amount: value.amount.value() as i64,
104        });
105
106        Ok(BurnTransactionData {
107            asset_amount: amount,
108        })
109    }
110}
111
112#[cfg(test)]
113mod tests {
114    use crate::error::Result;
115    use crate::model::{Amount, AssetId, BurnTransaction, BurnTransactionInfo, ByteString};
116    use serde_json::{json, Map, Value};
117    use std::borrow::Borrow;
118    use std::fs;
119
120    #[test]
121    fn test_json_to_burn_transaction() -> Result<()> {
122        let data =
123            fs::read_to_string("./tests/resources/burn_rs.json").expect("Unable to read file");
124        let json: Value = serde_json::from_str(&data).expect("failed to generate json from str");
125
126        let burn_from_json: BurnTransactionInfo = json.borrow().try_into()?;
127
128        assert_eq!(
129            "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
130            burn_from_json.amount().asset_id().unwrap().encoded()
131        );
132        assert_eq!(12, burn_from_json.amount().value());
133        Ok(())
134    }
135
136    #[test]
137    fn test_burn_transaction_to_json() -> Result<()> {
138        let burn_transaction = &BurnTransaction::new(Amount::new(
139            13,
140            Some(AssetId::from_string(
141                "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
142            )?),
143        ));
144        let map: Map<String, Value> = burn_transaction.try_into()?;
145        let json: Value = map.into();
146        let expected_json = json!({
147            "amount": 13,
148            "assetId": "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6"
149        });
150        assert_eq!(expected_json, json);
151        Ok(())
152    }
153}