tap_msg/message/
agent_management.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;
13use crate::message::Participant;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct AddAgents {
18 #[serde(rename = "transfer_id")]
20 pub transaction_id: String,
21
22 pub agents: Vec<Participant>,
24}
25
26impl AddAgents {
27 pub fn new(transaction_id: &str, agents: Vec<Participant>) -> Self {
29 Self {
30 transaction_id: transaction_id.to_string(),
31 agents,
32 }
33 }
34
35 pub fn add_agent(mut self, agent: Participant) -> Self {
37 self.agents.push(agent);
38 self
39 }
40}
41
42impl TapMessageBody for AddAgents {
43 fn message_type() -> &'static str {
44 "https://tap.rsvp/schema/1.0#add-agents"
45 }
46
47 fn validate(&self) -> Result<()> {
48 if self.transaction_id.is_empty() {
49 return Err(Error::Validation(
50 "Transaction ID is required in AddAgents".to_string(),
51 ));
52 }
53
54 if self.agents.is_empty() {
55 return Err(Error::Validation(
56 "At least one agent must be specified in AddAgents".to_string(),
57 ));
58 }
59
60 for agent in &self.agents {
62 if agent.id.is_empty() {
63 return Err(Error::Validation("Agent ID cannot be empty".to_string()));
64 }
65 }
66
67 Ok(())
68 }
69
70 fn to_didcomm(&self, from_did: &str) -> Result<PlainMessage> {
71 let mut body_json =
73 serde_json::to_value(self).map_err(|e| Error::SerializationError(e.to_string()))?;
74
75 if let Some(body_obj) = body_json.as_object_mut() {
77 body_obj.insert(
78 "@type".to_string(),
79 serde_json::Value::String(Self::message_type().to_string()),
80 );
81 }
82
83 let id = uuid::Uuid::new_v4().to_string();
85 let created_time = Utc::now().timestamp() as u64;
86
87 let message = PlainMessage {
89 id,
90 typ: "application/didcomm-plain+json".to_string(),
91 type_: Self::message_type().to_string(),
92 from: from_did.to_string(),
93 to: Vec::new(), thid: Some(self.transaction_id.clone()),
95 pthid: None,
96 created_time: Some(created_time),
97 expires_time: None,
98 extra_headers: std::collections::HashMap::new(),
99 from_prior: None,
100 body: body_json,
101 attachments: None,
102 };
103
104 Ok(message)
105 }
106}
107
108impl_tap_message!(AddAgents);
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct ReplaceAgent {
115 #[serde(rename = "transfer_id")]
117 pub transaction_id: String,
118
119 pub original: String,
121
122 pub replacement: Participant,
124}
125
126impl ReplaceAgent {
127 pub fn new(transaction_id: &str, original: &str, replacement: Participant) -> Self {
129 Self {
130 transaction_id: transaction_id.to_string(),
131 original: original.to_string(),
132 replacement,
133 }
134 }
135}
136
137impl TapMessageBody for ReplaceAgent {
138 fn message_type() -> &'static str {
139 "https://tap.rsvp/schema/1.0#replace-agent"
140 }
141
142 fn validate(&self) -> Result<()> {
143 if self.transaction_id.is_empty() {
144 return Err(Error::Validation(
145 "Transaction ID is required in ReplaceAgent".to_string(),
146 ));
147 }
148
149 if self.original.is_empty() {
150 return Err(Error::Validation(
151 "Original agent ID is required in ReplaceAgent".to_string(),
152 ));
153 }
154
155 if self.replacement.id.is_empty() {
156 return Err(Error::Validation(
157 "Replacement agent ID is required in ReplaceAgent".to_string(),
158 ));
159 }
160
161 Ok(())
162 }
163
164 fn to_didcomm(&self, from_did: &str) -> Result<PlainMessage> {
165 let mut body_json =
167 serde_json::to_value(self).map_err(|e| Error::SerializationError(e.to_string()))?;
168
169 if let Some(body_obj) = body_json.as_object_mut() {
171 body_obj.insert(
172 "@type".to_string(),
173 serde_json::Value::String(Self::message_type().to_string()),
174 );
175 }
176
177 let id = uuid::Uuid::new_v4().to_string();
179 let created_time = Utc::now().timestamp() as u64;
180
181 let message = PlainMessage {
183 id,
184 typ: "application/didcomm-plain+json".to_string(),
185 type_: Self::message_type().to_string(),
186 from: from_did.to_string(),
187 to: Vec::new(), thid: Some(self.transaction_id.clone()),
189 pthid: None,
190 created_time: Some(created_time),
191 expires_time: None,
192 extra_headers: std::collections::HashMap::new(),
193 from_prior: None,
194 body: body_json,
195 attachments: None,
196 };
197
198 Ok(message)
199 }
200}
201
202impl_tap_message!(ReplaceAgent);
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct RemoveAgent {
209 #[serde(rename = "transfer_id")]
211 pub transaction_id: String,
212
213 pub agent: String,
215}
216
217impl RemoveAgent {
218 pub fn new(transaction_id: &str, agent: &str) -> Self {
220 Self {
221 transaction_id: transaction_id.to_string(),
222 agent: agent.to_string(),
223 }
224 }
225}
226
227impl TapMessageBody for RemoveAgent {
228 fn message_type() -> &'static str {
229 "https://tap.rsvp/schema/1.0#remove-agent"
230 }
231
232 fn validate(&self) -> Result<()> {
233 if self.transaction_id.is_empty() {
234 return Err(Error::Validation(
235 "Transaction ID is required in RemoveAgent".to_string(),
236 ));
237 }
238
239 if self.agent.is_empty() {
240 return Err(Error::Validation(
241 "Agent ID is required in RemoveAgent".to_string(),
242 ));
243 }
244
245 Ok(())
246 }
247
248 fn to_didcomm(&self, from_did: &str) -> Result<PlainMessage> {
249 let mut body_json =
251 serde_json::to_value(self).map_err(|e| Error::SerializationError(e.to_string()))?;
252
253 if let Some(body_obj) = body_json.as_object_mut() {
255 body_obj.insert(
256 "@type".to_string(),
257 serde_json::Value::String(Self::message_type().to_string()),
258 );
259 }
260
261 let id = uuid::Uuid::new_v4().to_string();
263 let created_time = Utc::now().timestamp() as u64;
264
265 let message = PlainMessage {
267 id,
268 typ: "application/didcomm-plain+json".to_string(),
269 type_: Self::message_type().to_string(),
270 from: from_did.to_string(),
271 to: Vec::new(), thid: Some(self.transaction_id.clone()),
273 pthid: None,
274 created_time: Some(created_time),
275 expires_time: None,
276 extra_headers: std::collections::HashMap::new(),
277 from_prior: None,
278 body: body_json,
279 attachments: None,
280 };
281
282 Ok(message)
283 }
284}
285
286impl_tap_message!(RemoveAgent);