1use std::str::FromStr;
4
5use ave_identity::{DigestIdentifier, PublicKey, Signed};
6
7use crate::{
8 Namespace, SchemaType, ValueWrapper,
9 bridge::request::{
10 BridgeConfirmRequest, BridgeCreateRequest, BridgeEOLRequest,
11 BridgeEventRequest, BridgeFactRequest, BridgeRejectRequest,
12 BridgeSignedEventRequest, BridgeTransferRequest,
13 },
14 error::ConversionError,
15 request::{
16 ConfirmRequest, CreateRequest, EOLRequest, EventRequest, FactRequest,
17 RejectRequest, TransferRequest,
18 },
19 signature::BridgeSignature,
20};
21
22impl From<Signed<EventRequest>> for BridgeSignedEventRequest {
27 fn from(value: Signed<EventRequest>) -> Self {
28 let request = BridgeEventRequest::from(value.content().clone());
29 let signature = Some(BridgeSignature::from(value.signature().clone()));
30
31 Self { request, signature }
32 }
33}
34
35impl From<EventRequest> for BridgeSignedEventRequest {
36 fn from(value: EventRequest) -> Self {
37 let request = BridgeEventRequest::from(value);
38 let signature = None;
39
40 Self { request, signature }
41 }
42}
43
44impl From<EventRequest> for BridgeEventRequest {
45 fn from(request: EventRequest) -> Self {
46 match request {
47 EventRequest::Create(req) => Self::Create(req.into()),
48 EventRequest::Fact(req) => Self::Fact(req.into()),
49 EventRequest::Transfer(req) => Self::Transfer(req.into()),
50 EventRequest::EOL(req) => Self::Eol(req.into()),
51 EventRequest::Confirm(req) => Self::Confirm(req.into()),
52 EventRequest::Reject(req) => Self::Reject(req.into()),
53 }
54 }
55}
56
57impl TryFrom<BridgeEventRequest> for EventRequest {
58 type Error = ConversionError;
59
60 fn try_from(request: BridgeEventRequest) -> Result<Self, Self::Error> {
61 match request {
62 BridgeEventRequest::Create(req) => {
63 Ok(Self::Create(req.try_into()?))
64 }
65 BridgeEventRequest::Fact(req) => Ok(Self::Fact(req.try_into()?)),
66 BridgeEventRequest::Transfer(req) => {
67 Ok(Self::Transfer(req.try_into()?))
68 }
69 BridgeEventRequest::Eol(req) => Ok(Self::EOL(req.try_into()?)),
70 BridgeEventRequest::Confirm(req) => {
71 Ok(Self::Confirm(req.try_into()?))
72 }
73 BridgeEventRequest::Reject(req) => {
74 Ok(Self::Reject(req.try_into()?))
75 }
76 }
77 }
78}
79
80impl From<CreateRequest> for BridgeCreateRequest {
85 fn from(request: CreateRequest) -> Self {
86 Self {
87 name: request.name,
88 description: request.description,
89 governance_id: Some(request.governance_id.to_string()),
90 schema_id: request.schema_id.to_string(),
91 namespace: Some(request.namespace.to_string()),
92 }
93 }
94}
95
96impl TryFrom<BridgeCreateRequest> for CreateRequest {
97 type Error = ConversionError;
98
99 fn try_from(request: BridgeCreateRequest) -> Result<Self, Self::Error> {
100 let governance_id = if let Some(governance_id) = request.governance_id {
101 DigestIdentifier::from_str(&governance_id).map_err(|e| {
102 ConversionError::InvalidGovernanceId(e.to_string())
103 })?
104 } else {
105 DigestIdentifier::default()
106 };
107
108 let schema_id = SchemaType::from_str(&request.schema_id)
109 .map_err(ConversionError::InvalidSchemaId)?;
110
111 let namespace = request
112 .namespace
113 .map_or_else(Namespace::new, Namespace::from);
114
115 Ok(Self {
116 name: request.name,
117 description: request.description,
118 governance_id,
119 schema_id,
120 namespace,
121 })
122 }
123}
124
125impl From<FactRequest> for BridgeFactRequest {
130 fn from(request: FactRequest) -> Self {
131 Self {
132 subject_id: request.subject_id.to_string(),
133 payload: request.payload.0,
134 }
135 }
136}
137
138impl TryFrom<BridgeFactRequest> for FactRequest {
139 type Error = ConversionError;
140
141 fn try_from(request: BridgeFactRequest) -> Result<Self, Self::Error> {
142 let subject_id = DigestIdentifier::from_str(&request.subject_id)
143 .map_err(|e| ConversionError::InvalidSubjectId(e.to_string()))?;
144
145 Ok(Self {
146 subject_id,
147 payload: ValueWrapper(request.payload),
148 })
149 }
150}
151
152impl From<TransferRequest> for BridgeTransferRequest {
157 fn from(request: TransferRequest) -> Self {
158 Self {
159 subject_id: request.subject_id.to_string(),
160 new_owner: request.new_owner.to_string(),
161 }
162 }
163}
164
165impl TryFrom<BridgeTransferRequest> for TransferRequest {
166 type Error = ConversionError;
167
168 fn try_from(request: BridgeTransferRequest) -> Result<Self, Self::Error> {
169 let subject_id = DigestIdentifier::from_str(&request.subject_id)
170 .map_err(|e| ConversionError::InvalidSubjectId(e.to_string()))?;
171
172 let new_owner = PublicKey::from_str(&request.new_owner)
173 .map_err(|e| ConversionError::InvalidPublicKey(e.to_string()))?;
174
175 Ok(Self {
176 subject_id,
177 new_owner,
178 })
179 }
180}
181
182impl From<EOLRequest> for BridgeEOLRequest {
187 fn from(request: EOLRequest) -> Self {
188 Self {
189 subject_id: request.subject_id.to_string(),
190 }
191 }
192}
193
194impl TryFrom<BridgeEOLRequest> for EOLRequest {
195 type Error = ConversionError;
196
197 fn try_from(request: BridgeEOLRequest) -> Result<Self, Self::Error> {
198 let subject_id = DigestIdentifier::from_str(&request.subject_id)
199 .map_err(|e| ConversionError::InvalidSubjectId(e.to_string()))?;
200
201 Ok(Self { subject_id })
202 }
203}
204
205impl From<ConfirmRequest> for BridgeConfirmRequest {
210 fn from(request: ConfirmRequest) -> Self {
211 Self {
212 subject_id: request.subject_id.to_string(),
213 name_old_owner: request.name_old_owner,
214 }
215 }
216}
217
218impl TryFrom<BridgeConfirmRequest> for ConfirmRequest {
219 type Error = ConversionError;
220
221 fn try_from(request: BridgeConfirmRequest) -> Result<Self, Self::Error> {
222 let subject_id = DigestIdentifier::from_str(&request.subject_id)
223 .map_err(|e| ConversionError::InvalidSubjectId(e.to_string()))?;
224
225 Ok(Self {
226 subject_id,
227 name_old_owner: request.name_old_owner,
228 })
229 }
230}
231
232impl From<RejectRequest> for BridgeRejectRequest {
237 fn from(request: RejectRequest) -> Self {
238 Self {
239 subject_id: request.subject_id.to_string(),
240 }
241 }
242}
243
244impl TryFrom<BridgeRejectRequest> for RejectRequest {
245 type Error = ConversionError;
246
247 fn try_from(request: BridgeRejectRequest) -> Result<Self, Self::Error> {
248 let subject_id = DigestIdentifier::from_str(&request.subject_id)
249 .map_err(|e| ConversionError::InvalidSubjectId(e.to_string()))?;
250
251 Ok(Self { subject_id })
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use super::*;
258 use serde_json::json;
259
260 #[test]
261 fn test_fact_request_conversion() {
262 let bridge_fact = BridgeFactRequest {
263 subject_id: "BKZgYibuHNJjiNS179FUDpLGgdLq0C04TZRGb6AXMd1s"
264 .to_string(),
265 payload: json!({"test": "value"}),
266 };
267
268 let fact: Result<FactRequest, _> = bridge_fact.clone().try_into();
269 assert!(fact.is_ok());
270
271 let fact = fact.unwrap();
272 let bridge_back: BridgeFactRequest = fact.into();
273 assert_eq!(bridge_back.subject_id, bridge_fact.subject_id);
274 }
275
276 #[test]
277 fn test_create_request_conversion() {
278 let bridge_create = BridgeCreateRequest {
279 name: Some("Test".to_string()),
280 description: Some("Test description".to_string()),
281 governance_id: Some(
282 "BKZgYibuHNJjiNS179FUDpLGgdLq0C04TZRGb6AXMd1s".to_string(),
283 ),
284 schema_id: "governance".to_string(),
285 namespace: Some("test.namespace".to_string()),
286 };
287
288 let create: Result<CreateRequest, _> = bridge_create.try_into();
289 assert!(create.is_ok());
290 }
291
292 #[test]
293 fn test_create_request_missing_governance_id() {
294 let bridge_create = BridgeCreateRequest {
295 name: Some("Test".to_string()),
296 description: Some("Test description".to_string()),
297 governance_id: None,
298 schema_id: "governance".to_string(),
299 namespace: Some("test.namespace".to_string()),
300 };
301
302 let create: Result<CreateRequest, _> = bridge_create.try_into();
303 assert!(create.is_ok());
304 }
305
306 #[test]
307 fn test_invalid_subject_id() {
308 let bridge_fact = BridgeFactRequest {
309 subject_id: "invalid_id".to_string(),
310 payload: json!({"test": "value"}),
311 };
312
313 let fact: Result<FactRequest, _> = bridge_fact.try_into();
314 assert!(fact.is_err());
315 assert!(matches!(
316 fact.unwrap_err(),
317 ConversionError::InvalidSubjectId(_)
318 ));
319 }
320}