Skip to main content

xrpl/models/transactions/
mptoken_issuance_destroy.rs

1use alloc::borrow::Cow;
2
3use serde::{Deserialize, Serialize};
4use serde_with::skip_serializing_none;
5
6use crate::models::{
7    transactions::{Transaction, TransactionType},
8    Model, NoFlags, ValidateCurrencies, XRPLModelResult,
9};
10
11use super::mptoken_issuance_set::validate_mptoken_issuance_id;
12use super::{CommonFields, CommonTransactionBuilder};
13
14/// Destroys an existing MPToken issuance. Only the issuer can destroy an
15/// issuance, and only if there are no outstanding tokens held by others.
16///
17/// See MPTokenIssuanceDestroy:
18/// `<https://xrpl.org/docs/references/protocol/transactions/types/mptokenissuancedestroy>`
19#[skip_serializing_none]
20#[derive(
21    Debug,
22    Default,
23    Serialize,
24    Deserialize,
25    PartialEq,
26    Eq,
27    Clone,
28    xrpl_rust_macros::ValidateCurrencies,
29)]
30#[serde(rename_all = "PascalCase")]
31pub struct MPTokenIssuanceDestroy<'a> {
32    /// The base fields for all transaction models.
33    ///
34    /// See Transaction Common Fields:
35    /// `<https://xrpl.org/transaction-common-fields.html>`
36    #[serde(flatten)]
37    pub common_fields: CommonFields<'a, NoFlags>,
38    /// The MPToken issuance ID to destroy, encoded as a hex string.
39    #[serde(rename = "MPTokenIssuanceID")]
40    pub mptoken_issuance_id: Cow<'a, str>,
41}
42
43impl<'a> Model for MPTokenIssuanceDestroy<'a> {
44    fn get_errors(&self) -> XRPLModelResult<()> {
45        validate_mptoken_issuance_id(self.mptoken_issuance_id.as_ref())?;
46        self.validate_currencies()
47    }
48}
49
50impl<'a> Transaction<'a, NoFlags> for MPTokenIssuanceDestroy<'a> {
51    fn has_flag(&self, flag: &NoFlags) -> bool {
52        self.common_fields.has_flag(flag)
53    }
54
55    fn get_transaction_type(&self) -> &TransactionType {
56        self.common_fields.get_transaction_type()
57    }
58
59    fn get_common_fields(&self) -> &CommonFields<'_, NoFlags> {
60        self.common_fields.get_common_fields()
61    }
62
63    fn get_mut_common_fields(&mut self) -> &mut CommonFields<'a, NoFlags> {
64        self.common_fields.get_mut_common_fields()
65    }
66}
67
68impl<'a> CommonTransactionBuilder<'a, NoFlags> for MPTokenIssuanceDestroy<'a> {
69    fn get_mut_common_fields(&mut self) -> &mut CommonFields<'a, NoFlags> {
70        &mut self.common_fields
71    }
72
73    fn into_self(self) -> Self {
74        self
75    }
76}
77
78impl<'a> MPTokenIssuanceDestroy<'a> {
79    pub fn with_mptoken_issuance_id(mut self, id: Cow<'a, str>) -> Self {
80        self.mptoken_issuance_id = id;
81        self
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use crate::models::Model;
88
89    use super::*;
90    use crate::utils::testing::test_constants::*;
91
92    #[test]
93    fn test_serde() {
94        let txn = MPTokenIssuanceDestroy {
95            common_fields: CommonFields {
96                account: ACCOUNT_ISSUER.into(),
97                transaction_type: TransactionType::MPTokenIssuanceDestroy,
98                fee: Some("10".into()),
99                ..Default::default()
100            },
101            mptoken_issuance_id: "00000001A407AF5856CEFBF81F3D4A0000000000A407AF58".into(),
102        };
103
104        let json_str = serde_json::to_string(&txn).unwrap();
105        let deserialized: MPTokenIssuanceDestroy = serde_json::from_str(&json_str).unwrap();
106        assert_eq!(txn, deserialized);
107    }
108
109    #[test]
110    fn test_builder_pattern() {
111        let txn = MPTokenIssuanceDestroy {
112            common_fields: CommonFields {
113                account: ACCOUNT_ISSUER.into(),
114                transaction_type: TransactionType::MPTokenIssuanceDestroy,
115                ..Default::default()
116            },
117            ..Default::default()
118        }
119        .with_mptoken_issuance_id("00000001A407AF5856CEFBF81F3D4A0000000000A407AF58".into())
120        .with_fee("12".into())
121        .with_sequence(100);
122
123        assert_eq!(
124            txn.mptoken_issuance_id.as_ref(),
125            "00000001A407AF5856CEFBF81F3D4A0000000000A407AF58"
126        );
127        assert!(txn.validate().is_ok());
128    }
129
130    #[test]
131    fn test_default() {
132        let txn = MPTokenIssuanceDestroy {
133            common_fields: CommonFields {
134                account: ACCOUNT_ISSUER.into(),
135                transaction_type: TransactionType::MPTokenIssuanceDestroy,
136                ..Default::default()
137            },
138            mptoken_issuance_id: "00000001A407AF5856CEFBF81F3D4A0000000000A407AF58".into(),
139        };
140
141        assert!(txn.validate().is_ok());
142    }
143
144    #[test]
145    fn test_invalid_mptoken_issuance_id() {
146        let txn = MPTokenIssuanceDestroy {
147            common_fields: CommonFields {
148                account: ACCOUNT_ISSUER.into(),
149                transaction_type: TransactionType::MPTokenIssuanceDestroy,
150                ..Default::default()
151            },
152            // 32 hex chars; must be 48.
153            mptoken_issuance_id: "00000001A407AF5856CEFBF81F3D4A00".into(),
154        };
155
156        assert!(txn.validate().is_err());
157    }
158
159    #[test]
160    fn test_transaction_trait_methods() {
161        use crate::models::transactions::Transaction;
162        let mut txn = MPTokenIssuanceDestroy {
163            common_fields: CommonFields {
164                account: ACCOUNT_ISSUER.into(),
165                transaction_type: TransactionType::MPTokenIssuanceDestroy,
166                ..Default::default()
167            },
168            mptoken_issuance_id: "00000001A407AF5856CEFBF81F3D4A0000000000A407AF58".into(),
169        };
170        assert_eq!(
171            *txn.get_transaction_type(),
172            TransactionType::MPTokenIssuanceDestroy
173        );
174        assert_eq!(txn.get_common_fields().account.as_ref(), ACCOUNT_ISSUER);
175        // exercise get_mut_common_fields via Transaction trait
176        Transaction::get_mut_common_fields(&mut txn).sequence = Some(42);
177        assert_eq!(txn.common_fields.sequence, Some(42));
178    }
179}