waves_rust/model/transaction/
reissue_transaction.rs

1use crate::error::{Error, Result};
2use crate::model::{Amount, AssetId, ByteString};
3use crate::util::JsonDeserializer;
4use crate::waves_proto::{Amount as ProtoAmount, ReissueTransactionData};
5use serde_json::{Map, Value};
6
7const TYPE: u8 = 5;
8
9#[derive(Clone, Eq, PartialEq, Debug)]
10pub struct ReissueTransactionInfo {
11    amount: Amount,
12    reissuable: bool,
13}
14
15impl ReissueTransactionInfo {
16    pub fn new(amount: Amount, reissuable: bool) -> Self {
17        Self { amount, reissuable }
18    }
19
20    pub fn amount(&self) -> Amount {
21        self.amount.clone()
22    }
23
24    pub fn is_reissuable(&self) -> bool {
25        self.reissuable
26    }
27}
28
29impl TryFrom<&Value> for ReissueTransactionInfo {
30    type Error = Error;
31
32    fn try_from(value: &Value) -> Result<Self> {
33        let quantity = JsonDeserializer::safe_to_int_from_field(value, "quantity")?;
34        let asset_id = match value["assetId"].as_str() {
35            Some(asset) => Some(AssetId::from_string(asset)?),
36            None => None,
37        };
38        let reissuable = JsonDeserializer::safe_to_boolean_from_field(value, "reissuable")?;
39
40        Ok(ReissueTransactionInfo {
41            amount: Amount::new(quantity as u64, asset_id),
42            reissuable,
43        })
44    }
45}
46
47#[derive(Clone, Eq, PartialEq, Debug)]
48pub struct ReissueTransaction {
49    amount: Amount,
50    reissuable: bool,
51}
52
53impl ReissueTransaction {
54    pub fn new(amount: Amount, reissuable: bool) -> Self {
55        Self { amount, reissuable }
56    }
57
58    pub fn tx_type() -> u8 {
59        TYPE
60    }
61
62    pub fn amount(&self) -> Amount {
63        self.amount.clone()
64    }
65
66    pub fn is_reissuable(&self) -> bool {
67        self.reissuable
68    }
69}
70
71impl TryFrom<&Value> for ReissueTransaction {
72    type Error = Error;
73
74    fn try_from(value: &Value) -> Result<Self> {
75        let quantity = JsonDeserializer::safe_to_int_from_field(value, "quantity")?;
76        let asset_id = match value["assetId"].as_str() {
77            Some(asset) => Some(AssetId::from_string(asset)?),
78            None => None,
79        };
80        let reissuable = JsonDeserializer::safe_to_boolean_from_field(value, "reissuable")?;
81
82        Ok(ReissueTransaction {
83            amount: Amount::new(quantity as u64, asset_id),
84            reissuable,
85        })
86    }
87}
88
89impl TryFrom<&ReissueTransaction> for Map<String, Value> {
90    type Error = Error;
91
92    fn try_from(value: &ReissueTransaction) -> Result<Self> {
93        let mut issue_tx_json = Map::new();
94        issue_tx_json.insert(
95            "assetId".to_owned(),
96            value
97                .amount
98                .asset_id()
99                .map(|asset| asset.encoded().into())
100                .unwrap_or(Value::Null),
101        );
102        issue_tx_json.insert("quantity".to_owned(), value.amount.value().into());
103        issue_tx_json.insert("reissuable".to_owned(), value.reissuable.into());
104        Ok(issue_tx_json)
105    }
106}
107
108impl TryFrom<&ReissueTransaction> for ReissueTransactionData {
109    type Error = Error;
110
111    fn try_from(value: &ReissueTransaction) -> Result<Self> {
112        let asset_id = match value.amount.asset_id() {
113            Some(asset) => asset.bytes(),
114            None => vec![],
115        };
116        let amount = Some(ProtoAmount {
117            asset_id,
118            amount: value.amount.value() as i64,
119        });
120
121        Ok(ReissueTransactionData {
122            asset_amount: amount,
123            reissuable: value.reissuable,
124        })
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use crate::error::Result;
131    use crate::model::{Amount, AssetId, ByteString, ReissueTransaction, ReissueTransactionInfo};
132    use crate::waves_proto::ReissueTransactionData;
133    use serde_json::{json, Map, Value};
134    use std::borrow::Borrow;
135    use std::fs;
136
137    #[test]
138    fn test_json_to_reissue_transaction() {
139        let data =
140            fs::read_to_string("./tests/resources/reissue_rs.json").expect("Unable to read file");
141        let json: Value = serde_json::from_str(&data).expect("failed to generate json from str");
142
143        let reissue_from_json: ReissueTransactionInfo = json.borrow().try_into().unwrap();
144
145        assert_eq!(
146            "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
147            reissue_from_json
148                .amount()
149                .asset_id()
150                .expect("failed")
151                .encoded()
152        );
153        assert_eq!(12, reissue_from_json.amount().value());
154        assert_eq!(true, reissue_from_json.is_reissuable());
155    }
156
157    #[test]
158    fn test_reissue_to_proto() -> Result<()> {
159        let reissue_tx = &ReissueTransaction::new(
160            Amount::new(
161                32,
162                Some(AssetId::from_string(
163                    "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
164                )?),
165            ),
166            true,
167        );
168        let proto: ReissueTransactionData = reissue_tx.try_into()?;
169
170        assert_eq!(proto.reissuable, reissue_tx.is_reissuable());
171        let amount = proto.asset_amount.unwrap();
172        assert_eq!(amount.amount as u64, reissue_tx.amount().value());
173        assert_eq!(
174            amount.asset_id,
175            reissue_tx.amount().asset_id().unwrap().bytes()
176        );
177        Ok(())
178    }
179
180    #[test]
181    fn test_reissue_to_json() -> Result<()> {
182        let reissue_tx = &ReissueTransaction::new(
183            Amount::new(
184                32,
185                Some(AssetId::from_string(
186                    "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
187                )?),
188            ),
189            true,
190        );
191
192        let map: Map<String, Value> = reissue_tx.try_into()?;
193        let json: Value = map.into();
194        let expected_json = json!({
195            "assetId": "8bt2MZjuUCJPmfucPfaZPTXqrxmoCHCC8gVnbjZ7bhH6",
196            "quantity": 32,
197            "reissuable": true
198        });
199        assert_eq!(expected_json, json);
200        Ok(())
201    }
202}