tap_msg/message/
revert.rs1use chrono::Utc;
7use serde::{Deserialize, Serialize};
8
9use crate::didcomm::PlainMessage;
10use crate::error::{Error, Result};
11use crate::impl_tap_message;
12use crate::message::tap_message_trait::TapMessageBody;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct Revert {
17 pub transaction_id: String,
19
20 pub settlement_address: String,
22
23 pub reason: String,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub note: Option<String>,
29}
30
31impl Revert {
32 pub fn new(transaction_id: &str, settlement_address: &str, reason: &str) -> Self {
34 Self {
35 transaction_id: transaction_id.to_string(),
36 settlement_address: settlement_address.to_string(),
37 reason: reason.to_string(),
38 note: None,
39 }
40 }
41
42 pub fn with_note(
44 transaction_id: &str,
45 settlement_address: &str,
46 reason: &str,
47 note: &str,
48 ) -> Self {
49 Self {
50 transaction_id: transaction_id.to_string(),
51 settlement_address: settlement_address.to_string(),
52 reason: reason.to_string(),
53 note: Some(note.to_string()),
54 }
55 }
56}
57
58impl TapMessageBody for Revert {
59 fn message_type() -> &'static str {
60 "https://tap.rsvp/schema/1.0#revert"
61 }
62
63 fn validate(&self) -> Result<()> {
64 if self.transaction_id.is_empty() {
65 return Err(Error::Validation(
66 "Transaction ID is required in Revert".to_string(),
67 ));
68 }
69
70 if self.settlement_address.is_empty() {
71 return Err(Error::Validation(
72 "Settlement address is required in Revert".to_string(),
73 ));
74 }
75
76 if self.reason.is_empty() {
77 return Err(Error::Validation(
78 "Reason is required in Revert".to_string(),
79 ));
80 }
81
82 Ok(())
83 }
84
85 fn to_didcomm(&self, from_did: &str) -> Result<PlainMessage> {
86 let mut body_json =
88 serde_json::to_value(self).map_err(|e| Error::SerializationError(e.to_string()))?;
89
90 if let Some(body_obj) = body_json.as_object_mut() {
92 body_obj.insert(
93 "@type".to_string(),
94 serde_json::Value::String(Self::message_type().to_string()),
95 );
96 }
97
98 let id = uuid::Uuid::new_v4().to_string();
100 let created_time = Utc::now().timestamp() as u64;
101
102 let from = from_did.to_string();
104
105 let message = PlainMessage {
107 id,
108 typ: "application/didcomm-plain+json".to_string(),
109 type_: Self::message_type().to_string(),
110 from,
111 to: Vec::new(), thid: Some(self.transaction_id.clone()),
113 pthid: None,
114 created_time: Some(created_time),
115 expires_time: None,
116 extra_headers: std::collections::HashMap::new(),
117 from_prior: None,
118 body: body_json,
119 attachments: None,
120 };
121
122 Ok(message)
123 }
124}
125
126impl_tap_message!(Revert);