waves_rust/model/transaction/
reissue_transaction.rs1use 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}