From f4c8642fd298bf07413f20a6678fe5a4aae3cdf1 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea <98585737+bobozaur@users.noreply.github.com> Date: Wed, 13 Sep 2023 13:22:10 +0300 Subject: [PATCH] Feature/msg builders (#972) * Added builders for messages crate --------- Signed-off-by: Bogdan Mircea --- Cargo.lock | 22 +++ aries_vcx/src/common/ledger/transactions.rs | 40 +++-- .../connection/mediated_connection.rs | 39 ++-- aries_vcx/src/handlers/discovery/mod.rs | 40 +++-- aries_vcx/src/handlers/issuance/holder.rs | 22 ++- aries_vcx/src/handlers/issuance/issuer.rs | 91 +++++----- .../src/handlers/out_of_band/receiver.rs | 12 +- aries_vcx/src/handlers/out_of_band/sender.rs | 8 +- .../src/handlers/proof_presentation/prover.rs | 43 ++--- .../handlers/proof_presentation/verifier.rs | 38 ++-- aries_vcx/src/handlers/util.rs | 14 +- aries_vcx/src/protocols/common.rs | 19 +- .../src/protocols/connection/generic/mod.rs | 74 +++++--- .../src/protocols/connection/invitee/mod.rs | 55 +++--- .../connection/invitee/states/invited.rs | 5 +- .../src/protocols/connection/inviter/mod.rs | 54 +++--- .../connection/inviter/states/invited.rs | 6 +- aries_vcx/src/protocols/connection/mod.rs | 23 +-- .../issuance/holder/state_machine.rs | 34 ++-- .../issuance/issuer/state_machine.rs | 57 +++--- .../issuer/states/requested_received.rs | 2 - .../invitee/state_machine.rs | 97 +++++----- .../inviter/state_machine.rs | 58 +++--- aries_vcx/src/protocols/oob/mod.rs | 45 +++-- .../prover/state_machine.rs | 60 ++++--- .../states/presentation_proposal_sent.rs | 10 +- .../states/presentation_request_received.rs | 11 +- .../verifier/state_machine.rs | 71 ++++---- .../states/presentation_proposal_received.rs | 10 +- .../states/presentation_request_set.rs | 11 +- .../protocols/revocation_notification/mod.rs | 38 ++-- .../receiver/state_machine.rs | 42 +++-- .../sender/state_machine.rs | 31 ++-- aries_vcx/src/protocols/trustping/mod.rs | 23 ++- aries_vcx/src/utils/encryption_envelope.rs | 11 +- aries_vcx/tests/test_connection.rs | 16 +- aries_vcx/tests/test_creds_proofs.rs | 168 ++++++++++-------- aries_vcx/tests/utils/scenarios.rs | 138 ++++++++------ .../api_vcx/api_handle/mediated_connection.rs | 52 +++--- messages/Cargo.toml | 2 + messages/src/decorators/attachment.rs | 78 +++----- messages/src/decorators/localization.rs | 30 ++-- messages/src/decorators/please_ack.rs | 11 +- messages/src/decorators/thread.rs | 36 ++-- messages/src/decorators/timing.rs | 26 +-- messages/src/misc/mod.rs | 6 +- .../src/msg_fields/protocols/basic_message.rs | 27 +-- .../protocols/connection/invitation/mod.rs | 48 +++-- .../connection/invitation/pairwise.rs | 148 ++++++++------- .../protocols/connection/invitation/public.rs | 59 ++++-- .../msg_fields/protocols/connection/mod.rs | 3 +- .../protocols/connection/problem_report.rs | 40 ++--- .../protocols/connection/request.rs | 32 ++-- .../protocols/connection/response.rs | 37 ++-- .../msg_fields/protocols/cred_issuance/ack.rs | 42 +++-- .../cred_issuance/issue_credential.rs | 51 +++--- .../msg_fields/protocols/cred_issuance/mod.rs | 16 +- .../cred_issuance/offer_credential.rs | 49 ++--- .../protocols/cred_issuance/problem_report.rs | 111 +++++++++++- .../cred_issuance/propose_credential.rs | 55 +++--- .../cred_issuance/request_credential.rs | 32 ++-- .../protocols/discover_features/disclose.rs | 31 ++-- .../protocols/discover_features/mod.rs | 10 +- .../protocols/discover_features/query.rs | 65 ++++--- .../msg_fields/protocols/notification/ack.rs | 31 ++-- .../protocols/notification/problem_report.rs | 109 +++++++++++- .../protocols/out_of_band/invitation.rs | 52 +++--- .../msg_fields/protocols/out_of_band/reuse.rs | 30 ++-- .../protocols/out_of_band/reuse_accepted.rs | 30 ++-- .../msg_fields/protocols/present_proof/ack.rs | 42 +++-- .../protocols/present_proof/present.rs | 49 +++-- .../protocols/present_proof/problem_report.rs | 110 +++++++++++- .../protocols/present_proof/propose.rs | 98 +++++----- .../protocols/present_proof/request.rs | 34 ++-- .../msg_fields/protocols/report_problem.rs | 94 +++++----- .../msg_fields/protocols/revocation/ack.rs | 42 +++-- .../msg_fields/protocols/revocation/revoke.rs | 42 ++--- messages/src/msg_fields/protocols/routing.rs | 14 +- .../msg_fields/protocols/trust_ping/ping.rs | 15 +- .../protocols/trust_ping/ping_response.rs | 26 +-- messages/src/msg_parts.rs | 50 ++++-- wrappers/vcx-napi-rs/src/api/connection.rs | 22 ++- 82 files changed, 2026 insertions(+), 1499 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad9fe9db00..0fd5eb220d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3130,6 +3130,7 @@ version = "0.58.0" dependencies = [ "chrono", "derive_more", + "did_parser", "diddoc_legacy", "isolang", "lazy_static", @@ -3141,6 +3142,7 @@ dependencies = [ "strum_macros 0.24.3", "thiserror", "transitive", + "typed-builder", "url", ] @@ -5039,6 +5041,26 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "typed-builder" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6605aaa56cce0947127ffa0675a8a1b181f87773364390174de60a86ab9085f1" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a6a6884f6a890a012adcc20ce498f30ebdc70fb1ea242c333cc5f435b0b3871" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "typenum" version = "1.16.0" diff --git a/aries_vcx/src/common/ledger/transactions.rs b/aries_vcx/src/common/ledger/transactions.rs index 084c23430d..ec0d53517d 100644 --- a/aries_vcx/src/common/ledger/transactions.rs +++ b/aries_vcx/src/common/ledger/transactions.rs @@ -1,7 +1,7 @@ use bs58; use diddoc_legacy::aries::diddoc::AriesDidDoc; use diddoc_legacy::aries::service::AriesService; -use messages::msg_fields::protocols::connection::invitation::Invitation; +use messages::msg_fields::protocols::connection::invitation::{Invitation, InvitationContent}; use messages::msg_fields::protocols::out_of_band::invitation::OobService; use std::{collections::HashMap, sync::Arc}; @@ -93,25 +93,35 @@ pub async fn add_new_did( pub async fn into_did_doc(indy_ledger: &Arc, invitation: &AnyInvitation) -> VcxResult { let mut did_doc: AriesDidDoc = AriesDidDoc::default(); let (service_endpoint, recipient_keys, routing_keys) = match invitation { - AnyInvitation::Con(Invitation::Public(invitation)) => { - did_doc.set_id(invitation.content.did.to_string()); - let service = get_service(indy_ledger, &invitation.content.did) - .await - .unwrap_or_else(|err| { - error!("Failed to obtain service definition from the ledger: {}", err); - AriesService::default() - }); + AnyInvitation::Con(Invitation { + id, + content: InvitationContent::Public(content), + decorators, + }) => { + did_doc.set_id(content.did.to_string()); + let service = get_service(indy_ledger, &content.did).await.unwrap_or_else(|err| { + error!("Failed to obtain service definition from the ledger: {}", err); + AriesService::default() + }); (service.service_endpoint, service.recipient_keys, service.routing_keys) } - AnyInvitation::Con(Invitation::Pairwise(invitation)) => { - did_doc.set_id(invitation.id.clone()); + AnyInvitation::Con(Invitation { + id, + content: InvitationContent::Pairwise(content), + decorators, + }) => { + did_doc.set_id(id.clone()); ( - invitation.content.service_endpoint.clone(), - invitation.content.recipient_keys.clone(), - invitation.content.routing_keys.clone(), + content.service_endpoint.clone(), + content.recipient_keys.clone(), + content.routing_keys.clone(), ) } - AnyInvitation::Con(Invitation::PairwiseDID(_)) => { + AnyInvitation::Con(Invitation { + id, + content: InvitationContent::PairwiseDID(content), + decorators, + }) => { return Err(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidDid, format!("PairwiseDID invitation not supported yet!"), diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index a486a06fa0..c3cfadefa4 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -9,7 +9,7 @@ use futures::future::BoxFuture; use futures::stream::StreamExt; use messages::decorators::timing::Timing; use messages::msg_fields::protocols::basic_message::{BasicMessage, BasicMessageContent, BasicMessageDecorators}; -use messages::msg_fields::protocols::connection::invitation::Invitation; +use messages::msg_fields::protocols::connection::invitation::InvitationContent; use messages::msg_fields::protocols::connection::request::Request; use messages::msg_fields::protocols::connection::Connection; use messages::msg_fields::protocols::discover_features::disclose::Disclose; @@ -614,14 +614,16 @@ impl MediatedConnection { SmConnection::Invitee(sm_invitee) => { let (sm_invitee, can_autohop) = match message { Some(message) => match message { - AriesMessage::Connection(Connection::Invitation(Invitation::Public(invitation))) => ( - sm_invitee.handle_invitation(AnyInvitation::Con(Invitation::Public(invitation)))?, - false, - ), - AriesMessage::Connection(Connection::Invitation(Invitation::Pairwise(invitation))) => ( - sm_invitee.handle_invitation(AnyInvitation::Con(Invitation::Pairwise(invitation)))?, - false, - ), + AriesMessage::Connection(Connection::Invitation(invitation)) + if matches!(invitation.content, InvitationContent::Public(_)) => + { + (sm_invitee.handle_invitation(AnyInvitation::Con(invitation))?, false) + } + AriesMessage::Connection(Connection::Invitation(invitation)) + if matches!(invitation.content, InvitationContent::Pairwise(_)) => + { + (sm_invitee.handle_invitation(AnyInvitation::Con(invitation))?, false) + } AriesMessage::Connection(Connection::Response(response)) => { let send_message = self.send_message_closure_connection(Arc::clone(wallet)); ( @@ -807,15 +809,20 @@ impl MediatedConnection { Err(_) => { let now = Utc::now(); - let content = BasicMessageContent::new(message.to_owned(), now); - - let mut decorators = BasicMessageDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(now); + let content = BasicMessageContent::builder() + .content(message.to_owned()) + .sent_time(now) + .build(); - decorators.timing = Some(timing); + let decorators = BasicMessageDecorators::builder() + .timing(Timing::builder().out_time(now).build()) + .build(); - BasicMessage::with_decorators(Uuid::new_v4().to_string(), content, decorators).into() + BasicMessage::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } } } diff --git a/aries_vcx/src/handlers/discovery/mod.rs b/aries_vcx/src/handlers/discovery/mod.rs index 7532132a18..ca6b2a60ea 100644 --- a/aries_vcx/src/handlers/discovery/mod.rs +++ b/aries_vcx/src/handlers/discovery/mod.rs @@ -21,17 +21,25 @@ pub async fn send_discovery_query( pw_vk: &str, ) -> VcxResult<()> { let query = query.unwrap_or("*".to_owned()); - let mut content = QueryContent::new(query); - content.comment = comment; + let content = QueryContent::builder().query(query); - let mut decorators = QueryDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let content = if let Some(comment) = comment { + content.comment(comment).build() + } else { + content.build() + }; - let query = Query::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let decorators = QueryDecorators::builder() + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - send_message(Arc::clone(wallet), pw_vk.to_string(), did_doc.clone(), query.into()).await + let query = Query::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); + + send_message(Arc::clone(wallet), pw_vk.to_string(), did_doc.clone(), query).await } pub async fn respond_discovery_query( @@ -43,12 +51,16 @@ pub async fn respond_discovery_query( ) -> VcxResult<()> { let content = DiscloseContent::default(); - let mut decorators = DiscloseDecorators::new(Thread::new(query.id)); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = DiscloseDecorators::builder() + .thread(Thread::builder().thid(query.id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - let disclose = Disclose::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let disclose = Disclose::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); - send_message(Arc::clone(wallet), pw_vk.to_string(), did_doc.clone(), disclose.into()).await + send_message(Arc::clone(wallet), pw_vk.to_string(), did_doc.clone(), disclose).await } diff --git a/aries_vcx/src/handlers/issuance/holder.rs b/aries_vcx/src/handlers/issuance/holder.rs index de5fae59f9..225d77fce2 100644 --- a/aries_vcx/src/handlers/issuance/holder.rs +++ b/aries_vcx/src/handlers/issuance/holder.rs @@ -13,7 +13,7 @@ use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCrede use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential; use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; -use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; +use messages::msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}; use messages::msg_fields::protocols::report_problem::ProblemReport; use messages::msg_fields::protocols::revocation::revoke::Revoke; use messages::AriesMessage; @@ -25,13 +25,19 @@ use crate::handlers::revocation_notification::receiver::RevocationNotificationRe use crate::protocols::issuance::holder::state_machine::{HolderFullState, HolderSM, HolderState}; fn build_credential_ack(thread_id: &str) -> AckCredential { - let content = AckCredentialContent::new(AckStatus::Ok); - let mut decorators = AckDecorators::new(Thread::new(thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - AckCredential::with_decorators(Uuid::new_v4().to_string(), content, decorators) + let content = AckCredentialContent::builder() + .inner(AckContent::builder().status(AckStatus::Ok).build()) + .build(); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + AckCredential::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/aries_vcx/src/handlers/issuance/issuer.rs b/aries_vcx/src/handlers/issuance/issuer.rs index 0acffcc48f..f0f1c09e26 100644 --- a/aries_vcx/src/handlers/issuance/issuer.rs +++ b/aries_vcx/src/handlers/issuance/issuer.rs @@ -11,7 +11,6 @@ use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential; use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::msg_parts::MsgParts; use crate::errors::error::prelude::*; use crate::handlers::util::OfferInfo; @@ -46,7 +45,7 @@ fn _build_credential_preview(credential_json: &str) -> VcxResult { @@ -60,48 +59,54 @@ fn _build_credential_preview(credential_json: &str) -> VcxResult { for item in values_map.iter() { let (key, value) = item; - - let mut attr = CredentialAttr::new( - key.to_owned(), - value - .as_str() - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidOption, - "Credential values are currently only allowed to be strings", - ))? - .to_owned(), - ); - - attr.mime_type = Some(MimeType::Plain); - credential_preview.attributes.push(attr); + let value = value + .as_str() + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidOption, + "Credential values are currently only allowed to be strings", + ))? + .to_owned(); + let attr = CredentialAttr::builder() + .name(key.to_owned()) + .value(value) + .mime_type(MimeType::Plain) + .build(); + + attributes.push(attr); } } _ => {} }; - Ok(credential_preview) + + Ok(CredentialPreview::new(attributes)) } impl Issuer { @@ -279,22 +284,10 @@ impl Issuer { } AriesMessage::ReportProblem(report) => self.issuer_sm.clone().receive_problem_report(report)?, AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - self.issuer_sm.clone().receive_problem_report(report)? + self.issuer_sm.clone().receive_problem_report(report.into())? } AriesMessage::CredentialIssuance(CredentialIssuance::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - self.issuer_sm.clone().receive_problem_report(report)? + self.issuer_sm.clone().receive_problem_report(report.into())? } _ => self.issuer_sm.clone(), }; diff --git a/aries_vcx/src/handlers/out_of_band/receiver.rs b/aries_vcx/src/handlers/out_of_band/receiver.rs index 62d93fc187..ed2a7c2cc3 100644 --- a/aries_vcx/src/handlers/out_of_band/receiver.rs +++ b/aries_vcx/src/handlers/out_of_band/receiver.rs @@ -185,8 +185,10 @@ impl OutOfBandReceiver { if let Some(thread) = &mut offer.decorators.thread { thread.pthid = Some(self.oob.id.clone()); } else { - let mut thread = Thread::new(offer.id.clone()); - thread.pthid = Some(self.oob.id.clone()); + let thread = Thread::builder() + .thid(offer.id.clone()) + .pthid(self.oob.id.clone()) + .build(); offer.decorators.thread = Some(thread); } @@ -205,8 +207,10 @@ impl OutOfBandReceiver { if let Some(thread) = &mut request.decorators.thread { thread.pthid = Some(self.oob.id.clone()); } else { - let mut thread = Thread::new(request.id.clone()); - thread.pthid = Some(self.oob.id.clone()); + let thread = Thread::builder() + .thid(request.id.clone()) + .pthid(self.oob.id.clone()) + .build(); request.decorators.thread = Some(thread); } diff --git a/aries_vcx/src/handlers/out_of_band/sender.rs b/aries_vcx/src/handlers/out_of_band/sender.rs index 92fb9813ba..16fdf26056 100644 --- a/aries_vcx/src/handlers/out_of_band/sender.rs +++ b/aries_vcx/src/handlers/out_of_band/sender.rs @@ -26,11 +26,15 @@ pub struct OutOfBandSender { impl OutOfBandSender { pub fn create() -> Self { let id = Uuid::new_v4().to_string(); - let content = InvitationContent::new(Vec::new()); + let content = InvitationContent::builder().services(Vec::new()).build(); let decorators = InvitationDecorators::default(); Self { - oob: Invitation::with_decorators(id, content, decorators), + oob: Invitation::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(), } } diff --git a/aries_vcx/src/handlers/proof_presentation/prover.rs b/aries_vcx/src/handlers/proof_presentation/prover.rs index 3ad6f3aa35..e5300b3260 100644 --- a/aries_vcx/src/handlers/proof_presentation/prover.rs +++ b/aries_vcx/src/handlers/proof_presentation/prover.rs @@ -14,8 +14,6 @@ use messages::msg_fields::protocols::present_proof::propose::{ }; use messages::msg_fields::protocols::present_proof::request::RequestPresentation; use messages::msg_fields::protocols::present_proof::PresentProof; -use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::msg_parts::MsgParts; use messages::AriesMessage; use uuid::Uuid; @@ -174,22 +172,10 @@ impl Prover { } AriesMessage::ReportProblem(report) => self.prover_sm.clone().receive_presentation_reject(report)?, AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - self.prover_sm.clone().receive_presentation_reject(report)? + self.prover_sm.clone().receive_presentation_reject(report.into())? } AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - self.prover_sm.clone().receive_presentation_reject(report)? + self.prover_sm.clone().receive_presentation_reject(report.into())? } _ => self.prover_sm.clone(), }; @@ -229,16 +215,23 @@ impl Prover { })?; let thread_id = self.prover_sm.get_thread_id()?; let id = Uuid::new_v4().to_string(); - let content = ProposePresentationContent::new(presentation_preview); - let mut decorators = ProposePresentationDecorators::default(); - let thread = Thread::new(thread_id.to_owned()); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.thread = Some(thread); - decorators.timing = Some(timing); - let proposal = ProposePresentation::with_decorators(id, content, decorators); - (self.prover_sm.clone().negotiate_presentation().await?, proposal.into()) + let content = ProposePresentationContent::builder() + .presentation_proposal(presentation_preview) + .build(); + + let decorators = ProposePresentationDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + let proposal = ProposePresentation::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); + + (self.prover_sm.clone().negotiate_presentation().await?, proposal) } (None, None) => { return Err(AriesVcxError::from_msg( diff --git a/aries_vcx/src/handlers/proof_presentation/verifier.rs b/aries_vcx/src/handlers/proof_presentation/verifier.rs index 693a6d67cc..c83673dd3c 100644 --- a/aries_vcx/src/handlers/proof_presentation/verifier.rs +++ b/aries_vcx/src/handlers/proof_presentation/verifier.rs @@ -7,8 +7,6 @@ use messages::msg_fields::protocols::present_proof::present::Presentation; use messages::msg_fields::protocols::present_proof::propose::ProposePresentation; use messages::msg_fields::protocols::present_proof::request::RequestPresentation; use messages::msg_fields::protocols::present_proof::PresentProof; -use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::msg_parts::MsgParts; use messages::AriesMessage; use crate::common::proofs::proof_request::PresentationRequestData; @@ -160,30 +158,18 @@ impl Verifier { self.verifier_sm.clone().receive_presentation_request_reject(report)?, None, ), - AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - ( - self.verifier_sm.clone().receive_presentation_request_reject(report)?, - None, - ) - } - AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - ( - self.verifier_sm.clone().receive_presentation_request_reject(report)?, - None, - ) - } + AriesMessage::Notification(Notification::ProblemReport(report)) => ( + self.verifier_sm + .clone() + .receive_presentation_request_reject(report.into())?, + None, + ), + AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => ( + self.verifier_sm + .clone() + .receive_presentation_request_reject(report.into())?, + None, + ), _ => (self.verifier_sm.clone(), None), }; self.verifier_sm = verifier_sm; diff --git a/aries_vcx/src/handlers/util.rs b/aries_vcx/src/handlers/util.rs index e7e44f6775..96918fa97f 100644 --- a/aries_vcx/src/handlers/util.rs +++ b/aries_vcx/src/handlers/util.rs @@ -63,8 +63,12 @@ macro_rules! get_attach_as_string { macro_rules! make_attach_from_str { ($str_attach:expr, $id:expr) => {{ let attach_type = messages::decorators::attachment::AttachmentType::Base64(base64::encode($str_attach)); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); + let attach_data = messages::decorators::attachment::AttachmentData::builder() + .content(attach_type) + .build(); + let mut attach = messages::decorators::attachment::Attachment::builder() + .data(attach_data) + .build(); attach.id = Some($id); attach.mime_type = Some(messages::misc::MimeType::Json); attach @@ -85,9 +89,7 @@ pub fn verify_thread_id(thread_id: &str, message: &AriesMessage) -> VcxResult<() } let is_match = match message { AriesMessage::BasicMessage(msg) => matches_opt_thread_id!(msg, thread_id), - AriesMessage::Connection(Connection::Invitation(Invitation::Public(msg))) => msg.id == thread_id, - AriesMessage::Connection(Connection::Invitation(Invitation::Pairwise(msg))) => msg.id == thread_id, - AriesMessage::Connection(Connection::Invitation(Invitation::PairwiseDID(msg))) => msg.id == thread_id, + AriesMessage::Connection(Connection::Invitation(msg)) => msg.id == thread_id, AriesMessage::Connection(Connection::ProblemReport(msg)) => matches_thread_id!(msg, thread_id), AriesMessage::Connection(Connection::Request(msg)) => matches_opt_thread_id!(msg, thread_id), AriesMessage::Connection(Connection::Response(msg)) => matches_thread_id!(msg, thread_id), @@ -165,7 +167,7 @@ pub enum AnyInvitation { impl AnyInvitation { pub fn id(&self) -> &str { match self { - AnyInvitation::Con(invitation) => &invitation.id(), + AnyInvitation::Con(invitation) => &invitation.id, AnyInvitation::Oob(invitation) => &invitation.id, } } diff --git a/aries_vcx/src/protocols/common.rs b/aries_vcx/src/protocols/common.rs index 273ee083ed..592d67cfa9 100644 --- a/aries_vcx/src/protocols/common.rs +++ b/aries_vcx/src/protocols/common.rs @@ -1,17 +1,26 @@ use messages::{ decorators::thread::Thread, - msg_fields::protocols::report_problem::{ProblemReport, ProblemReportContent, ProblemReportDecorators}, + msg_fields::protocols::report_problem::{ + Description, ProblemReport, ProblemReportContent, ProblemReportDecorators, + }, }; use uuid::Uuid; pub fn build_problem_report_msg(comment: Option, thread_id: &str) -> ProblemReport { let id = Uuid::new_v4().to_string(); - let content = ProblemReportContent::new(comment.unwrap_or_default()); + let content = ProblemReportContent::builder() + .description(Description::builder().code(comment.unwrap_or_default()).build()) + .build(); - let mut decorators = ProblemReportDecorators::default(); - decorators.thread = Some(Thread::new(thread_id.to_owned())); + let decorators = ProblemReportDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .build(); - ProblemReport::with_decorators(id, content, decorators) + ProblemReport::builder() + .id(id) + .content(content) + .decorators(decorators) + .build() } // #[cfg(test)] diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 262bf8081c..8c7b222337 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -216,9 +216,7 @@ mod connection_serde_tests { use chrono::Utc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; - use messages::msg_fields::protocols::connection::invitation::{ - Invitation, PairwiseInvitation, PairwiseInvitationContent, PwInvitationDecorators, - }; + use messages::msg_fields::protocols::connection::invitation::{Invitation, InvitationContent}; use messages::msg_fields::protocols::connection::request::{Request, RequestContent, RequestDecorators}; use messages::msg_fields::protocols::connection::response::{Response, ResponseContent, ResponseDecorators}; use messages::msg_fields::protocols::connection::ConnectionData; @@ -386,16 +384,18 @@ mod connection_serde_tests { async fn make_invitee_invited() -> InviteeConnection { let indy_ledger: Arc = Arc::new(MockLedger {}); - let content = PairwiseInvitationContent::new( - String::new(), - vec![PW_KEY.to_owned()], - Vec::new(), - SERVICE_ENDPOINT.parse().unwrap(), - ); + let content = InvitationContent::builder_pairwise() + .label(String::new()) + .recipient_keys(vec![PW_KEY.to_owned()]) + .service_endpoint(SERVICE_ENDPOINT.parse().unwrap()) + .build(); - let decorators = PwInvitationDecorators::default(); - let pw_invite = PairwiseInvitation::with_decorators(Uuid::new_v4().to_string(), content, decorators); - let invitation = AnyInvitation::Con(Invitation::Pairwise(pw_invite)); + let pw_invite = Invitation::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .build(); + + let invitation = AnyInvitation::Con(pw_invite); make_invitee_initial() .await @@ -425,13 +425,17 @@ mod connection_serde_tests { let sig_data = sign_connection_response(&wallet, PW_KEY, &con_data).await.unwrap(); - let content = ResponseContent::new(sig_data); - let mut decorators = ResponseDecorators::new(Thread::new(con.thread_id().to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let content = ResponseContent::builder().connection_sig(sig_data).build(); + let decorators = ResponseDecorators::builder() + .thread(Thread::builder().thid(con.thread_id().to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - let response = Response::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let response = Response::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); let con = con.handle_response(&wallet, response, &MockTransport).await.unwrap(); @@ -461,14 +465,21 @@ mod connection_serde_tests { con_data.did_doc.set_recipient_keys(vec![PW_KEY.to_owned()]); con_data.did_doc.set_routing_keys(Vec::new()); - let content = RequestContent::new(PW_KEY.to_owned(), con_data); - let mut decorators = RequestDecorators::default(); - decorators.thread = Some(Thread::new(con.thread_id().to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let content = RequestContent::builder() + .label(PW_KEY.to_owned()) + .connection(con_data) + .build(); + + let decorators = RequestDecorators::builder() + .thread(Thread::builder().thid(con.thread_id().to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - let request = Request::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let request = Request::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); con.handle_request(&wallet, request, new_service_endpoint, new_routing_keys, &MockTransport) .await @@ -478,10 +489,17 @@ mod connection_serde_tests { async fn make_inviter_completed() -> InviterConnection { let con = make_inviter_requested().await; - let content = AckContent::new(AckStatus::Ok); - let decorators = AckDecorators::new(Thread::new(con.thread_id().to_owned())); + let content = AckContent::builder().status(AckStatus::Ok).build(); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(con.thread_id().to_owned()).build()) + .build(); + + let msg = Ack::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); - let msg = Ack::with_decorators(Uuid::new_v4().to_string(), content, decorators).into(); con.acknowledge_connection(&msg).unwrap() } diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 9c2804c5d2..6a068d0e59 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -10,7 +10,7 @@ use messages::{ decorators::{thread::Thread, timing::Timing}, msg_fields::protocols::{ connection::{ - invitation::Invitation, + invitation::InvitationContent, request::{Request, RequestContent, RequestDecorators}, response::Response, ConnectionData, @@ -100,12 +100,12 @@ impl InviteeConnection { did_doc.set_recipient_keys(recipient_keys); let con_data = ConnectionData::new(self.pairwise_info.pw_did.to_string(), did_doc); - let content = RequestContent::new(self.source_id.to_string(), con_data); + let content = RequestContent::builder() + .label(self.source_id.to_string()) + .connection(con_data) + .build(); - let mut decorators = RequestDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = RequestDecorators::builder().timing(Timing::builder().out_time(Utc::now()).build()); // Depending on the invitation type, we set the connection's thread ID // and the request parent and thread ID differently. @@ -119,22 +119,27 @@ impl InviteeConnection { // When the invitation is Pairwise, it is designed to be sent to a single invitee. // In this case, we reuse the invitation ID (current thread ID) as the thread ID // in both the connection and the request. - let (thread_id, thread) = match &self.state.invitation { - AnyInvitation::Con(Invitation::Public(_)) | AnyInvitation::Oob(_) => { - let mut thread = Thread::new(id.clone()); - thread.pthid = Some(self.state.thread_id().to_owned()); - - (id.clone(), thread) - } - AnyInvitation::Con(Invitation::Pairwise(_)) | AnyInvitation::Con(Invitation::PairwiseDID(_)) => { - let thread = Thread::new(self.state.thread_id().to_owned()); - (self.state.thread_id().to_owned(), thread) - } + let thread = match &self.state.invitation { + AnyInvitation::Oob(invite) => Thread::builder().thid(id.clone()).pthid(invite.id.clone()).build(), + AnyInvitation::Con(invite) => match invite.content { + InvitationContent::Public(_) => Thread::builder() + .thid(id.clone()) + .pthid(self.state.thread_id().to_owned()) + .build(), + InvitationContent::Pairwise(_) | InvitationContent::PairwiseDID(_) => { + Thread::builder().thid(self.state.thread_id().to_owned()).build() + } + }, }; - decorators.thread = Some(thread); + let thread_id = thread.thid.clone(); + let decorators = decorators.thread(thread).build(); - let request = Request::with_decorators(id, content, decorators); + let request = Request::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); Ok(Connection { state: Requested::new(self.state.did_doc, thread_id, request), @@ -217,14 +222,14 @@ impl InviteeConnection { /// Will error out if sending the message fails. pub fn get_ack(&self) -> Ack { let id = Uuid::new_v4().to_string(); - let content = AckContent::new(AckStatus::Ok); + let content = AckContent::builder().status(AckStatus::Ok).build(); - let mut decorators = AckDecorators::new(Thread::new(self.state.thread_id.clone())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(self.state.thread_id.clone()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - Ack::with_decorators(id, content, decorators) + Ack::builder().id(id).content(content).decorators(decorators).build() } } diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index c877c248eb..66d913fd47 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,5 +1,4 @@ use diddoc_legacy::aries::diddoc::AriesDidDoc; -use messages::msg_fields::protocols::connection::invitation::Invitation; use crate::{ handlers::util::AnyInvitation, @@ -29,9 +28,7 @@ impl BootstrapDidDoc for Invited {} impl ThreadId for Invited { fn thread_id(&self) -> &str { match &self.invitation { - AnyInvitation::Con(Invitation::Public(i)) => i.id.as_str(), - AnyInvitation::Con(Invitation::Pairwise(i)) => i.id.as_str(), - AnyInvitation::Con(Invitation::PairwiseDID(i)) => i.id.as_str(), + AnyInvitation::Con(i) => i.id.as_str(), AnyInvitation::Oob(i) => i.id.as_str(), } } diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index bc8a95b53d..4c4d258706 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -7,9 +7,7 @@ use chrono::Utc; use diddoc_legacy::aries::diddoc::AriesDidDoc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::connection::invitation::{ - Invitation, PairwiseInvitation, PairwiseInvitationContent, PwInvitationDecorators, -}; +use messages::msg_fields::protocols::connection::invitation::{Invitation, InvitationContent}; use messages::msg_fields::protocols::connection::request::Request; use messages::msg_fields::protocols::connection::response::{Response, ResponseContent, ResponseDecorators}; use messages::msg_fields::protocols::connection::ConnectionData; @@ -44,18 +42,16 @@ impl InviterConnection { /// Generates a pairwise [`Invitation`] and transitions to [`InviterConnection`]. pub fn create_invitation(self, routing_keys: Vec, service_endpoint: Url) -> InviterConnection { let id = Uuid::new_v4().to_string(); - let content = PairwiseInvitationContent::new( - self.source_id.clone(), - vec![self.pairwise_info.pw_vk.clone()], - routing_keys, - service_endpoint, - ); - - let decorators = PwInvitationDecorators::default(); + let content = InvitationContent::builder_pairwise() + .label(self.source_id.clone()) + .recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .routing_keys(routing_keys) + .service_endpoint(service_endpoint) + .build(); - let invite = PairwiseInvitation::with_decorators(id, content, decorators); + let invite = Invitation::builder().id(id).content(content).build(); - let invitation = AnyInvitation::Con(Invitation::Pairwise(invite)); + let invitation = AnyInvitation::Con(invite); Connection { source_id: self.source_id, @@ -82,18 +78,16 @@ impl InviterConnection { // for backwards compatibility. pub fn into_invited(self, thread_id: &str) -> InviterConnection { let id = thread_id.to_owned(); - let content = PairwiseInvitationContent::new( - self.source_id.clone(), - vec![self.pairwise_info.pw_vk.clone()], - vec![], - "https://dummy.dummy/dummy".parse().expect("url should be valid"), - ); - let decorators = PwInvitationDecorators::default(); + let content = InvitationContent::builder_pairwise() + .label(self.source_id.clone()) + .recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .service_endpoint("https://dummy.dummy/dummy".parse().expect("url should be valid")) + .build(); - let invite = PairwiseInvitation::with_decorators(id, content, decorators); + let invite = Invitation::builder().id(id).content(content).build(); - let invitation = AnyInvitation::Con(Invitation::Pairwise(invite)); + let invitation = AnyInvitation::Con(invite); Connection { source_id: self.source_id, @@ -130,14 +124,18 @@ impl InviterConnection { let con_sig = sign_connection_response(wallet, &self.pairwise_info.pw_vk, &con_data).await?; - let content = ResponseContent::new(con_sig); + let content = ResponseContent::builder().connection_sig(con_sig).build(); - let mut decorators = ResponseDecorators::new(Thread::new(thread_id)); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = ResponseDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - Ok(Response::with_decorators(id, content, decorators)) + Ok(Response::builder() + .id(id) + .content(content) + .decorators(decorators) + .build()) } /// Processes a [`Request`] and transitions to [`InviterConnection`]. diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index cfc497dce4..b3fc718469 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -1,5 +1,3 @@ -use messages::msg_fields::protocols::connection::invitation::Invitation; - use crate::{ handlers::util::AnyInvitation, protocols::connection::trait_bounds::{HandleProblem, ThreadId}, @@ -19,9 +17,7 @@ impl Invited { impl ThreadId for Invited { fn thread_id(&self) -> &str { match &self.invitation { - AnyInvitation::Con(Invitation::Public(i)) => i.id.as_str(), - AnyInvitation::Con(Invitation::Pairwise(i)) => i.id.as_str(), - AnyInvitation::Con(Invitation::PairwiseDID(i)) => i.id.as_str(), + AnyInvitation::Con(i) => i.id.as_str(), AnyInvitation::Oob(i) => i.id.as_str(), } } diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 74041e3b72..0916d043b4 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -74,7 +74,7 @@ impl Connection { } pub fn protocols(&self) -> Vec { - let query = QueryContent::new("*".to_owned()); + let query = QueryContent::builder().query("*".to_owned()).build(); query.lookup() } } @@ -134,15 +134,18 @@ where where E: Error, { - let mut content = ProblemReportContent::default(); - content.explain = Some(err.to_string()); - - let mut decorators = ProblemReportDecorators::new(Thread::new(thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - ProblemReport::with_decorators(Uuid::new_v4().to_string(), content, decorators) + let content = ProblemReportContent::builder().explain(err.to_string()).build(); + + let decorators = ProblemReportDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + ProblemReport::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } async fn send_problem_report( diff --git a/aries_vcx/src/protocols/issuance/holder/state_machine.rs b/aries_vcx/src/protocols/issuance/holder/state_machine.rs index 3e7b5cfb79..667cee474b 100644 --- a/aries_vcx/src/protocols/issuance/holder/state_machine.rs +++ b/aries_vcx/src/protocols/issuance/holder/state_machine.rs @@ -6,7 +6,6 @@ use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use chrono::Utc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::cred_issuance::ack::{AckCredential, AckCredentialContent}; use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential; use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential; use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; @@ -14,7 +13,6 @@ use messages::msg_fields::protocols::cred_issuance::request_credential::{ RequestCredential, RequestCredentialContent, RequestCredentialDecorators, }; use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; -use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; use messages::msg_fields::protocols::report_problem::ProblemReport; use messages::AriesMessage; use uuid::Uuid; @@ -69,21 +67,23 @@ impl fmt::Display for HolderFullState { } fn _build_credential_request_msg(credential_request_attach: String, thread_id: &str) -> RequestCredential { - let content = RequestCredentialContent::new(vec![make_attach_from_str!( - &credential_request_attach, - AttachmentId::CredentialRequest.as_ref().to_string() - )]); - - let mut decorators = RequestCredentialDecorators::default(); - - let thread = Thread::new(thread_id.to_owned()); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - - decorators.thread = Some(thread); - decorators.timing = Some(timing); - - RequestCredential::with_decorators(Uuid::new_v4().to_string(), content, decorators) + let content = RequestCredentialContent::builder() + .requests_attach(vec![make_attach_from_str!( + &credential_request_attach, + AttachmentId::CredentialRequest.as_ref().to_string() + )]) + .build(); + + let decorators = RequestCredentialDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + RequestCredential::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } impl HolderSM { diff --git a/aries_vcx/src/protocols/issuance/issuer/state_machine.rs b/aries_vcx/src/protocols/issuance/issuer/state_machine.rs index 54f2c7d737..bb74ab7368 100644 --- a/aries_vcx/src/protocols/issuance/issuer/state_machine.rs +++ b/aries_vcx/src/protocols/issuance/issuer/state_machine.rs @@ -94,15 +94,23 @@ pub struct IssuerSM { fn build_credential_message(libindy_credential: String, thread_id: String) -> IssueCredential { let id = Uuid::new_v4().to_string(); - let content = IssueCredentialContent::new(vec![make_attach_from_str!( - &libindy_credential, - AttachmentId::Credential.as_ref().to_string() - )]); - - let mut decorators = IssueCredentialDecorators::new(Thread::new(id.clone())); - decorators.thread.thid = thread_id.clone(); - decorators.please_ack = Some(PleaseAck::new(vec![])); - IssueCredential::with_decorators(id, content, decorators) + let content = IssueCredentialContent::builder() + .credentials_attach(vec![make_attach_from_str!( + &libindy_credential, + AttachmentId::Credential.as_ref().to_string() + )]) + .build(); + + let decorators = IssueCredentialDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .please_ack(PleaseAck::builder().on(vec![]).build()) + .build(); + + IssueCredential::builder() + .id(id) + .content(content) + .decorators(decorators) + .build() } fn build_credential_offer( @@ -113,21 +121,28 @@ fn build_credential_offer( ) -> VcxResult { let id = thread_id.to_owned(); - let mut content = OfferCredentialContent::new( - credential_preview, - vec![make_attach_from_str!( + let content = OfferCredentialContent::builder() + .credential_preview(credential_preview) + .offers_attach(vec![make_attach_from_str!( &credential_offer, AttachmentId::CredentialOffer.as_ref().to_string() - )], - ); - content.comment = comment; + )]); - let mut decorators = OfferCredentialDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let content = if let Some(comment) = comment { + content.comment(comment).build() + } else { + content.build() + }; + + let decorators = OfferCredentialDecorators::builder() + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - Ok(OfferCredential::with_decorators(id, content, decorators)) + Ok(OfferCredential::builder() + .id(id) + .content(content) + .decorators(decorators) + .build()) } impl IssuerSM { @@ -377,7 +392,7 @@ impl IssuerSM { ) .await { - Ok((mut msg_issue_credential, cred_rev_id)) => { + Ok((msg_issue_credential, cred_rev_id)) => { // todo: have constructor for this IssuerFullState::CredentialSet(CredentialSetState { msg_issue_credential, diff --git a/aries_vcx/src/protocols/issuance/issuer/states/requested_received.rs b/aries_vcx/src/protocols/issuance/issuer/states/requested_received.rs index ec021c301e..53d275b1ad 100644 --- a/aries_vcx/src/protocols/issuance/issuer/states/requested_received.rs +++ b/aries_vcx/src/protocols/issuance/issuer/states/requested_received.rs @@ -1,8 +1,6 @@ use crate::handlers::util::Status; use crate::protocols::issuance::issuer::state_machine::RevocationInfoV1; -use crate::protocols::issuance::issuer::states::credential_set::CredentialSetState; use crate::protocols::issuance::issuer::states::finished::FinishedState; -use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential; use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential; use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential; use messages::msg_fields::protocols::report_problem::ProblemReport; diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs index 40937cf988..67a12b0c8a 100644 --- a/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs @@ -17,7 +17,7 @@ use chrono::Utc; use diddoc_legacy::aries::diddoc::AriesDidDoc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::connection::invitation::Invitation; +use messages::msg_fields::protocols::connection::invitation::InvitationContent; use messages::msg_fields::protocols::connection::problem_report::{ ProblemReport, ProblemReportContent, ProblemReportDecorators, }; @@ -159,7 +159,7 @@ impl SmConnectionInvitee { } pub fn get_protocols(&self) -> Vec { - let query = QueryContent::new("*".to_owned()); + let query = QueryContent::builder().query("*".to_owned()).build(); query.lookup() } @@ -223,34 +223,33 @@ impl SmConnectionInvitee { did_doc.set_id(self.pairwise_info.pw_did.clone()); let con_data = ConnectionData::new(self.pairwise_info.pw_did.to_string(), did_doc); - let content = RequestContent::new(self.source_id.to_string(), con_data); - - let mut decorators = RequestDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - let (thread_id, thread) = match &state.invitation { - AnyInvitation::Con(Invitation::Public(_)) => { - let mut thread = Thread::new(id.clone()); - thread.pthid = Some(self.thread_id.clone()); - - (id.clone(), thread) - } - AnyInvitation::Con(Invitation::Pairwise(_)) | AnyInvitation::Con(Invitation::PairwiseDID(_)) => { - let thread = Thread::new(self.thread_id.clone()); - (self.thread_id.clone(), thread) - } - AnyInvitation::Oob(invite) => { - let mut thread = Thread::new(id.clone()); - thread.pthid = Some(invite.id.clone()); - (id.clone(), thread) - } + let content = RequestContent::builder() + .label(self.source_id.to_string()) + .connection(con_data) + .build(); + + let decorators = RequestDecorators::builder().timing(Timing::builder().out_time(Utc::now()).build()); + + let thread = match &state.invitation { + AnyInvitation::Oob(invite) => Thread::builder().thid(id.clone()).pthid(invite.id.clone()).build(), + AnyInvitation::Con(invite) => match invite.content { + InvitationContent::Public(_) => { + Thread::builder().thid(id.clone()).pthid(self.thread_id.clone()).build() + } + InvitationContent::Pairwise(_) | InvitationContent::PairwiseDID(_) => { + Thread::builder().thid(self.thread_id.clone()).build() + } + }, }; - decorators.thread = Some(thread); + let thread_id = thread.thid.clone(); + let decorators = decorators.thread(thread).build(); - let request = Request::with_decorators(id, content, decorators); + let request = Request::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); Ok((request, thread_id)) } @@ -264,13 +263,17 @@ impl SmConnectionInvitee { fn build_connection_ack_msg(&self) -> VcxResult { match &self.state { InviteeFullState::Responded(_) => { - let content = AckContent::new(AckStatus::Ok); - let mut decorators = AckDecorators::new(Thread::new(self.thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - Ok(Ack::with_decorators(Uuid::new_v4().to_string(), content, decorators)) + let content = AckContent::builder().status(AckStatus::Ok).build(); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(self.thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + Ok(Ack::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build()) } _ => Err(AriesVcxError::from_msg( AriesVcxErrorKind::NotReady, @@ -283,9 +286,7 @@ impl SmConnectionInvitee { let Self { state, .. } = self; let thread_id = match &invitation { - AnyInvitation::Con(Invitation::Public(i)) => i.id.clone(), - AnyInvitation::Con(Invitation::Pairwise(i)) => i.id.clone(), - AnyInvitation::Con(Invitation::PairwiseDID(i)) => i.id.clone(), + AnyInvitation::Con(i) => i.id.clone(), AnyInvitation::Oob(i) => i.id.clone(), }; @@ -383,16 +384,18 @@ impl SmConnectionInvitee { InviteeFullState::Responded((state, con_data).into()) } Err(err) => { - let mut content = ProblemReportContent::default(); - content.explain = Some(err.to_string()); - - let mut decorators = ProblemReportDecorators::new(Thread::new(self.thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - let problem_report = - ProblemReport::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let content = ProblemReportContent::builder().explain(err.to_string()).build(); + + let decorators = ProblemReportDecorators::builder() + .thread(Thread::builder().thid(self.thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + let problem_report: ProblemReport = ProblemReport::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); send_message( problem_report.clone().into(), diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs b/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs index 7ce8da5612..69da81bbfe 100644 --- a/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs +++ b/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs @@ -7,9 +7,7 @@ use chrono::Utc; use diddoc_legacy::aries::diddoc::AriesDidDoc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::connection::invitation::{ - Invitation, PairwiseInvitation, PairwiseInvitationContent, PwInvitationDecorators, -}; +use messages::msg_fields::protocols::connection::invitation::{Invitation, PairwiseInvitationContent}; use messages::msg_fields::protocols::connection::problem_report::{ ProblemReport, ProblemReportContent, ProblemReportDecorators, }; @@ -144,7 +142,7 @@ impl SmConnectionInviter { } pub fn get_protocols(&self) -> Vec { - let query = QueryContent::new("*".to_owned()); + let query = QueryContent::builder().query("*".to_owned()).build(); query.lookup() } @@ -208,18 +206,16 @@ impl SmConnectionInviter { let state = match self.state { InviterFullState::Initial(state) => { let id = self.thread_id.clone(); - let content = PairwiseInvitationContent::new( - self.source_id.clone(), - vec![self.pairwise_info.pw_vk.clone()], - routing_keys, - service_endpoint, - ); - - let decorators = PwInvitationDecorators::default(); + let content = PairwiseInvitationContent::builder() + .label(self.source_id.clone()) + .recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .routing_keys(routing_keys) + .service_endpoint(service_endpoint) + .build(); - let invite = PairwiseInvitation::with_decorators(id, content, decorators); + let invite = Invitation::builder().id(id).content(content).build(); - let invitation = AnyInvitation::Con(Invitation::Pairwise(invite)); + let invitation = AnyInvitation::Con(invite); InviterFullState::Invited((state, invitation).into()) } @@ -244,16 +240,18 @@ impl SmConnectionInviter { let (state, thread_id) = match self.state { InviterFullState::Invited(_) | InviterFullState::Initial(_) => { if let Err(err) = request.content.connection.did_doc.validate() { - let mut content = ProblemReportContent::default(); - content.explain = Some(err.to_string()); + let content = ProblemReportContent::builder().explain(err.to_string()).build(); - let mut decorators = ProblemReportDecorators::new(Thread::new(self.thread_id.clone())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = ProblemReportDecorators::builder() + .thread(Thread::builder().thid(self.thread_id.clone()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - let problem_report = - ProblemReport::with_decorators(Uuid::new_v4().to_string(), content, decorators); + let problem_report: ProblemReport = ProblemReport::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build(); let sender_vk = self.pairwise_info().pw_vk.clone(); let did_doc = request.content.connection.did_doc.clone(); @@ -373,14 +371,18 @@ impl SmConnectionInviter { let con_sig = sign_connection_response(wallet, &self.pairwise_info.pw_vk, &con_data).await?; - let content = ResponseContent::new(con_sig); + let content = ResponseContent::builder().connection_sig(con_sig).build(); - let mut decorators = ResponseDecorators::new(Thread::new(thread_id)); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = ResponseDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - Ok(Response::with_decorators(id, content, decorators)) + Ok(Response::builder() + .id(id) + .content(content) + .decorators(decorators) + .build()) } _ => Err(AriesVcxError::from_msg( AriesVcxErrorKind::NotReady, diff --git a/aries_vcx/src/protocols/oob/mod.rs b/aries_vcx/src/protocols/oob/mod.rs index a9a1075ad7..6d7b79c509 100644 --- a/aries_vcx/src/protocols/oob/mod.rs +++ b/aries_vcx/src/protocols/oob/mod.rs @@ -3,28 +3,27 @@ use chrono::Utc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; use messages::msg_fields::protocols::out_of_band::invitation::Invitation; -use messages::msg_fields::protocols::out_of_band::reuse::{ - HandshakeReuse, HandshakeReuseContent, HandshakeReuseDecorators, -}; +use messages::msg_fields::protocols::out_of_band::reuse::{HandshakeReuse, HandshakeReuseDecorators}; use messages::msg_fields::protocols::out_of_band::reuse_accepted::{ - HandshakeReuseAccepted, HandshakeReuseAcceptedContent, HandshakeReuseAcceptedDecorators, + HandshakeReuseAccepted, HandshakeReuseAcceptedDecorators, }; use uuid::Uuid; pub fn build_handshake_reuse_msg(oob_invitation: &Invitation) -> HandshakeReuse { let id = Uuid::new_v4().to_string(); - let content = HandshakeReuseContent::default(); - - let mut thread = Thread::new(id.clone()); - thread.pthid = Some(oob_invitation.id.clone()); - let mut decorators = HandshakeReuseDecorators::new(thread); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = HandshakeReuseDecorators::builder() + .thread( + Thread::builder() + .thid(id.clone()) + .pthid(oob_invitation.id.clone()) + .build(), + ) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - HandshakeReuse::with_decorators(id, content, decorators) + HandshakeReuse::builder().id(id).decorators(decorators).build() } pub fn build_handshake_reuse_accepted_msg(handshake_reuse: &HandshakeReuse) -> VcxResult { @@ -40,19 +39,15 @@ pub fn build_handshake_reuse_accepted_msg(handshake_reuse: &HandshakeReuse) -> V ))? .to_owned(); - let content = HandshakeReuseAcceptedContent::default(); - let mut thread = Thread::new(thread_id); - thread.pthid = Some(pthread_id); - - let decorators = HandshakeReuseAcceptedDecorators::new(thread); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); + let decorators = HandshakeReuseAcceptedDecorators::builder() + .thread(Thread::builder().thid(thread_id).pthid(pthread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - Ok(HandshakeReuseAccepted::with_decorators( - Uuid::new_v4().to_string(), - content, - decorators, - )) + Ok(HandshakeReuseAccepted::builder() + .id(Uuid::new_v4().to_string()) + .decorators(decorators) + .build()) } // #[cfg(test)] diff --git a/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs b/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs index 1c3f5ffd2a..6fa4d35d67 100644 --- a/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs +++ b/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs @@ -79,16 +79,23 @@ impl fmt::Display for ProverFullState { fn build_presentation_msg(thread_id: &str, presentation_attachment: String) -> VcxResult { let id = Uuid::new_v4().to_string(); - let content = PresentationContent::new(vec![make_attach_from_str!( - &presentation_attachment, - AttachmentId::Presentation.as_ref().to_string() - )]); - let mut decorators = PresentationDecorators::new(Thread::new(thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - Ok(Presentation::with_decorators(id, content, decorators)) + let content = PresentationContent::builder() + .presentations_attach(vec![make_attach_from_str!( + &presentation_attachment, + AttachmentId::Presentation.as_ref().to_string() + )]) + .build(); + + let decorators = PresentationDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + Ok(Presentation::builder() + .id(id) + .content(content) + .decorators(decorators) + .build()) } impl Default for ProverFullState { @@ -119,24 +126,37 @@ impl ProverSM { ProverFullState::Initial(_) => { let id = self.thread_id.clone(); let preview = PresentationPreview::new(proposal_data.attributes, proposal_data.predicates); - let mut content = ProposePresentationContent::new(preview); - content.comment = proposal_data.comment; + let content = ProposePresentationContent::builder().presentation_proposal(preview); - let decorators = ProposePresentationDecorators::default(); + let content = if let Some(comment) = proposal_data.comment { + content.comment(comment).build() + } else { + content.build() + }; - let proposal = ProposePresentation::with_decorators(id, content, decorators); + let proposal = ProposePresentation::builder().id(id).content(content).build(); ProverFullState::PresentationProposalSent(PresentationProposalSent::new(proposal)) } ProverFullState::PresentationRequestReceived(_) => { let id = Uuid::new_v4().to_string(); let preview = PresentationPreview::new(proposal_data.attributes, proposal_data.predicates); - let mut content = ProposePresentationContent::new(preview); - content.comment = proposal_data.comment; - let mut decorators = ProposePresentationDecorators::default(); - decorators.thread = Some(Thread::new(self.thread_id.clone())); - - let proposal = ProposePresentation::with_decorators(id, content, decorators); + let content = ProposePresentationContent::builder().presentation_proposal(preview); + let content = if let Some(comment) = proposal_data.comment { + content.comment(comment).build() + } else { + content.build() + }; + + let decorators = ProposePresentationDecorators::builder() + .thread(Thread::builder().thid(self.thread_id.clone()).build()) + .build(); + + let proposal = ProposePresentation::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); ProverFullState::PresentationProposalSent(PresentationProposalSent::new(proposal)) } s => { diff --git a/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_proposal_sent.rs b/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_proposal_sent.rs index 712ee80549..794ba1cd22 100644 --- a/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_proposal_sent.rs +++ b/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_proposal_sent.rs @@ -1,5 +1,5 @@ use messages::msg_fields::protocols::present_proof::propose::{ - PresentationPreview, ProposePresentation, ProposePresentationContent, ProposePresentationDecorators, + PresentationPreview, ProposePresentation, ProposePresentationContent, }; use uuid::Uuid; @@ -12,11 +12,13 @@ impl Default for PresentationProposalSent { fn default() -> Self { let id = Uuid::new_v4().to_string(); let preview = PresentationPreview::new(Vec::new(), Vec::new()); - let content = ProposePresentationContent::new(preview); - let decorators = ProposePresentationDecorators::default(); + + let content = ProposePresentationContent::builder() + .presentation_proposal(preview) + .build(); Self { - proposal: ProposePresentation::with_decorators(id, content, decorators), + proposal: ProposePresentation::builder().id(id).content(content).build(), } } } diff --git a/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_request_received.rs b/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_request_received.rs index 9e2479473d..5d859c7296 100644 --- a/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_request_received.rs +++ b/aries_vcx/src/protocols/proof_presentation/prover/states/presentation_request_received.rs @@ -4,9 +4,7 @@ use std::sync::Arc; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use messages::msg_fields::protocols::present_proof::present::Presentation; -use messages::msg_fields::protocols::present_proof::request::{ - RequestPresentation, RequestPresentationContent, RequestPresentationDecorators, -}; +use messages::msg_fields::protocols::present_proof::request::{RequestPresentation, RequestPresentationContent}; use messages::msg_fields::protocols::report_problem::ProblemReport; use uuid::Uuid; @@ -26,11 +24,12 @@ pub struct PresentationRequestReceived { impl Default for PresentationRequestReceived { fn default() -> Self { let id = Uuid::new_v4().to_string(); - let content = RequestPresentationContent::new(Vec::new()); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(Vec::new()) + .build(); Self { - presentation_request: RequestPresentation::with_decorators(id, content, decorators), + presentation_request: RequestPresentation::builder().id(id).content(content).build(), } } } diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs b/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs index cbf0ca4cfd..8841d8d4d3 100644 --- a/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs +++ b/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs @@ -8,11 +8,9 @@ use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; -use messages::msg_fields::protocols::present_proof::ack::{AckPresentation, AckPresentationContent}; -use messages::msg_fields::protocols::present_proof::problem_report::{ - PresentProofProblemReport, PresentProofProblemReportContent, -}; +use messages::msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}; +use messages::msg_fields::protocols::present_proof::ack::AckPresentation; +use messages::msg_fields::protocols::present_proof::problem_report::PresentProofProblemReport; use messages::msg_fields::protocols::present_proof::request::{ RequestPresentation, RequestPresentationContent, RequestPresentationDecorators, }; @@ -20,7 +18,6 @@ use messages::msg_fields::protocols::present_proof::{ present::Presentation, propose::ProposePresentation, PresentProof, }; use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::msg_parts::MsgParts; use messages::AriesMessage; use crate::common::proofs::proof_request::PresentationRequestData; @@ -79,13 +76,18 @@ impl Default for VerifierFullState { } pub fn build_verification_ack(thread_id: &str) -> AckPresentation { - let content = AckPresentationContent::new(AckStatus::Ok); - let mut decorators = AckDecorators::new(Thread::new(thread_id.to_owned())); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - AckPresentation::with_decorators(Uuid::new_v4().to_string(), content, decorators) + let content = AckContent::builder().status(AckStatus::Ok).build(); + + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(thread_id.to_owned()).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + AckPresentation::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } pub fn build_starting_presentation_request( @@ -95,18 +97,26 @@ pub fn build_starting_presentation_request( ) -> VcxResult { let id = thread_id.to_owned(); - let mut content = RequestPresentationContent::new(vec![make_attach_from_str!( + let content = RequestPresentationContent::builder().request_presentations_attach(vec![make_attach_from_str!( &json!(request_data).to_string(), AttachmentId::PresentationRequest.as_ref().to_string() )]); - content.comment = comment; - let mut decorators = RequestPresentationDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - Ok(RequestPresentation::with_decorators(id, content, decorators)) + let content = if let Some(comment) = comment { + content.comment(comment).build() + } else { + content.build() + }; + + let decorators = RequestPresentationDecorators::builder() + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + Ok(RequestPresentation::builder() + .id(id) + .content(content) + .decorators(decorators) + .build()) } impl VerifierSM { @@ -261,18 +271,13 @@ impl VerifierSM { )), Status::Success => Ok(build_problem_report_msg(None, &self.thread_id).into()), Status::Failed(problem_report) | Status::Declined(problem_report) => { - let MsgParts { - id, - content, - decorators, - } = problem_report.clone(); - - let problem_report = PresentProofProblemReport::with_decorators( - id, - PresentProofProblemReportContent(content), - decorators, - ); - Ok(problem_report.into()) + let problem_report = PresentProofProblemReport::builder() + .id(problem_report.id.clone()) + .content(problem_report.content.clone().into()) + .decorators(problem_report.decorators.clone()) + .build(); + + Ok(problem_report) } } } diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_proposal_received.rs b/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_proposal_received.rs index f374422993..99f602566c 100644 --- a/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_proposal_received.rs +++ b/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_proposal_received.rs @@ -1,5 +1,5 @@ use messages::msg_fields::protocols::present_proof::{ - propose::{PresentationPreview, ProposePresentation, ProposePresentationContent, ProposePresentationDecorators}, + propose::{PresentationPreview, ProposePresentation, ProposePresentationContent}, request::RequestPresentation, }; use uuid::Uuid; @@ -14,11 +14,13 @@ impl Default for PresentationProposalReceivedState { fn default() -> Self { let id = Uuid::new_v4().to_string(); let preview = PresentationPreview::new(Vec::new(), Vec::new()); - let content = ProposePresentationContent::new(preview); - let decorators = ProposePresentationDecorators::default(); + + let content = ProposePresentationContent::builder() + .presentation_proposal(preview) + .build(); Self { - presentation_proposal: ProposePresentation::with_decorators(id, content, decorators), + presentation_proposal: ProposePresentation::builder().id(id).content(content).build(), presentation_request: None, } } diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_request_set.rs b/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_request_set.rs index fff99339f8..447d42bc26 100644 --- a/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_request_set.rs +++ b/aries_vcx/src/protocols/proof_presentation/verifier/states/presentation_request_set.rs @@ -1,6 +1,4 @@ -use messages::msg_fields::protocols::present_proof::request::{ - RequestPresentation, RequestPresentationContent, RequestPresentationDecorators, -}; +use messages::msg_fields::protocols::present_proof::request::{RequestPresentation, RequestPresentationContent}; use uuid::Uuid; use crate::protocols::proof_presentation::verifier::states::presentation_request_sent::PresentationRequestSentState; @@ -13,11 +11,12 @@ pub struct PresentationRequestSetState { impl Default for PresentationRequestSetState { fn default() -> Self { let id = Uuid::new_v4().to_string(); - let content = RequestPresentationContent::new(Vec::new()); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(Vec::new()) + .build(); Self { - presentation_request: RequestPresentation::with_decorators(id, content, decorators), + presentation_request: RequestPresentation::builder().id(id).content(content).build(), } } } diff --git a/aries_vcx/src/protocols/revocation_notification/mod.rs b/aries_vcx/src/protocols/revocation_notification/mod.rs index 8d0d7c3ea5..d422d1a19f 100644 --- a/aries_vcx/src/protocols/revocation_notification/mod.rs +++ b/aries_vcx/src/protocols/revocation_notification/mod.rs @@ -25,39 +25,23 @@ pub mod test_utils { String::from("12") } - pub fn _comment() -> Option { - Some("Comment.".to_string()) + pub fn _comment() -> String { + "Comment.".to_string() } pub fn _revocation_notification(ack_on: Vec) -> Revoke { let id = Uuid::new_v4().to_string(); - let mut content = RevokeContent::new( - format!("{}::{}", _rev_reg_id(), _cred_rev_id()), - MaybeKnown::Known(RevocationFormat::IndyAnoncreds), - ); - content.comment = _comment(); + let content = RevokeContent::builder() + .credential_id(format!("{}::{}", _rev_reg_id(), _cred_rev_id())) + .revocation_format(MaybeKnown::Known(RevocationFormat::IndyAnoncreds)) + .comment(_comment()) + .build(); - let mut decorators = RevokeDecorators::default(); - let please_ack = PleaseAck::new(ack_on); - decorators.please_ack = Some(please_ack); + let decorators = RevokeDecorators::builder() + .please_ack(PleaseAck::builder().on(ack_on).build()) + .build(); - Revoke::with_decorators(id, content, decorators) - } - - pub fn _revocation_notification_invalid_format() -> Revoke { - let id = Uuid::new_v4().to_string(); - - let mut content = RevokeContent::new( - format!("{}::{}", _rev_reg_id(), _cred_rev_id()), - MaybeKnown::Known(RevocationFormat::IndyAnoncreds), - ); - content.comment = _comment(); - - let mut decorators = RevokeDecorators::default(); - let please_ack = PleaseAck::new(vec![AckOn::Receipt]); - decorators.please_ack = Some(please_ack); - - Revoke::with_decorators(id, content, decorators) + Revoke::builder().id(id).content(content).decorators(decorators).build() } } diff --git a/aries_vcx/src/protocols/revocation_notification/receiver/state_machine.rs b/aries_vcx/src/protocols/revocation_notification/receiver/state_machine.rs index 0ca56224b6..a8888323e6 100644 --- a/aries_vcx/src/protocols/revocation_notification/receiver/state_machine.rs +++ b/aries_vcx/src/protocols/revocation_notification/receiver/state_machine.rs @@ -2,8 +2,8 @@ use chrono::Utc; use messages::decorators::please_ack::AckOn; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; -use messages::msg_fields::protocols::revocation::ack::{AckRevoke, AckRevokeContent}; +use messages::msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}; +use messages::msg_fields::protocols::revocation::ack::AckRevoke; use messages::msg_fields::protocols::revocation::revoke::{RevocationFormat, Revoke}; use shared_vcx::maybe_known::MaybeKnown; use uuid::Uuid; @@ -83,7 +83,7 @@ impl RevocationNotificationReceiverSM { .unwrap_or(false) { let id = Uuid::new_v4().to_string(); - let content = AckRevokeContent::new(AckStatus::Ok); + let content = AckContent::builder().status(AckStatus::Ok).build(); let thread_id = notification .decorators @@ -92,13 +92,18 @@ impl RevocationNotificationReceiverSM { .map(|t| t.thid.clone()) .unwrap_or(notification.id.clone()); - let mut decorators = AckDecorators::new(Thread::new(thread_id)); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - let ack = AckRevoke::with_decorators(id, content, decorators); - send_message(ack.into()).await?; + let ack = AckRevoke::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); + + send_message(ack).await?; ReceiverFullState::Finished(FinishedState::new(notification)) } else { ReceiverFullState::NotificationReceived(NotificationReceivedState::new(notification)) @@ -130,7 +135,7 @@ impl RevocationNotificationReceiverSM { } let id = Uuid::new_v4().to_string(); - let content = AckRevokeContent::new(AckStatus::Ok); + let content = AckContent::builder().status(AckStatus::Ok).build(); let thread_id = notification .decorators @@ -139,13 +144,18 @@ impl RevocationNotificationReceiverSM { .map(|t| t.thid.clone()) .unwrap_or(notification.id.clone()); - let mut decorators = AckDecorators::new(Thread::new(thread_id)); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = AckDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + let ack = AckRevoke::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); - let ack = AckRevoke::with_decorators(id, content, decorators); - send_message(ack.into()).await?; + send_message(ack).await?; ReceiverFullState::Finished(FinishedState::new(notification)) } _ => { diff --git a/aries_vcx/src/protocols/revocation_notification/sender/state_machine.rs b/aries_vcx/src/protocols/revocation_notification/sender/state_machine.rs index 0b57a76382..c542cc5c94 100644 --- a/aries_vcx/src/protocols/revocation_notification/sender/state_machine.rs +++ b/aries_vcx/src/protocols/revocation_notification/sender/state_machine.rs @@ -72,26 +72,31 @@ impl RevocationNotificationSenderSM { let id = Uuid::new_v4().to_string(); - let mut content = RevokeContent::new( - format!("{rev_reg_id}::{cred_rev_id}"), - MaybeKnown::Known(RevocationFormat::IndyAnoncreds), - ); - content.comment = comment; + let content = RevokeContent::builder() + .credential_id(format!("{rev_reg_id}::{cred_rev_id}")) + .revocation_format(MaybeKnown::Known(RevocationFormat::IndyAnoncreds)); - let mut decorators = RevokeDecorators::default(); - let please_ack = PleaseAck::new(ack_on); - decorators.please_ack = Some(please_ack); + let content = if let Some(comment) = comment { + content.comment(comment).build() + } else { + content.build() + }; + + let decorators = RevokeDecorators::builder() + .please_ack(PleaseAck::builder().on(ack_on).build()) + .build(); - let rev_msg = Revoke::with_decorators(id, content, decorators); + let rev_msg: Revoke = Revoke::builder().id(id).content(content).decorators(decorators).build(); send_message(rev_msg.clone().into()).await?; - if !rev_msg + let is_finished = !rev_msg .decorators .please_ack .as_ref() .map(|d| d.on.is_empty()) - .unwrap_or(false) - { + .unwrap_or(false); + + if is_finished { SenderFullState::Finished(FinishedState::new(rev_msg, None)) } else { SenderFullState::NotificationSent(NotificationSentState::new(rev_msg)) @@ -142,7 +147,7 @@ pub mod test_utils { SenderConfigBuilder::default() .rev_reg_id(_rev_reg_id()) .cred_rev_id(_cred_rev_id()) - .comment(_comment()) + .comment(Some(_comment())) .ack_on(ack_on) .build() .unwrap() diff --git a/aries_vcx/src/protocols/trustping/mod.rs b/aries_vcx/src/protocols/trustping/mod.rs index ad295684bd..7c5973bf9f 100644 --- a/aries_vcx/src/protocols/trustping/mod.rs +++ b/aries_vcx/src/protocols/trustping/mod.rs @@ -4,7 +4,7 @@ use messages::{ decorators::{thread::Thread, timing::Timing}, msg_fields::protocols::trust_ping::{ ping::{Ping, PingContent, PingDecorators}, - ping_response::{PingResponse, PingResponseContent, PingResponseDecorators}, + ping_response::{PingResponse, PingResponseDecorators}, }, AriesMessage, }; @@ -19,7 +19,11 @@ pub fn build_ping(request_response: bool, comment: Option) -> Ping { timing.out_time = Some(Utc::now()); decorators.timing = Some(timing); - Ping::with_decorators(Uuid::new_v4().to_string(), content, decorators) + Ping::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } pub fn build_ping_response(ping: &Ping) -> PingResponse { @@ -31,14 +35,15 @@ pub fn build_ping_response(ping: &Ping) -> PingResponse { .unwrap_or(ping.id.as_str()) .to_owned(); - let content = PingResponseContent::default(); - let thread = Thread::new(thread_id); - let mut decorators = PingResponseDecorators::new(thread); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); + let decorators = PingResponseDecorators::builder() + .thread(Thread::builder().thid(thread_id).build()) + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); - PingResponse::with_decorators(Uuid::new_v4().to_string(), content, decorators) + PingResponse::builder() + .id(Uuid::new_v4().to_string()) + .decorators(decorators) + .build() } pub fn build_ping_response_msg(ping: &Ping) -> AriesMessage { diff --git a/aries_vcx/src/utils/encryption_envelope.rs b/aries_vcx/src/utils/encryption_envelope.rs index fa8ec9446d..92d0497599 100644 --- a/aries_vcx/src/utils/encryption_envelope.rs +++ b/aries_vcx/src/utils/encryption_envelope.rs @@ -90,8 +90,15 @@ impl EncryptionEnvelope { to: &str, routing_key: &str, ) -> VcxResult> { - let content = ForwardContent::new(to.to_string(), serde_json::from_slice(&message)?); - let message = Forward::new(Uuid::new_v4().to_string(), content); + let content = ForwardContent::builder() + .to(to.to_string()) + .msg(serde_json::from_slice(&message)?) + .build(); + + let message: Forward = Forward::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .build(); let message = json!(AriesMessage::from(message)).to_string(); let receiver_keys = json!(vec![routing_key]).to_string(); diff --git a/aries_vcx/tests/test_connection.rs b/aries_vcx/tests/test_connection.rs index 0a489c3425..96ddfa4a3c 100644 --- a/aries_vcx/tests/test_connection.rs +++ b/aries_vcx/tests/test_connection.rs @@ -26,15 +26,17 @@ use crate::utils::test_agent::{create_test_agent, create_test_agent_trustee}; fn build_basic_message(content: String) -> BasicMessage { let now = Utc::now(); - let content = BasicMessageContent::new(content, now); + let content = BasicMessageContent::builder().content(content).sent_time(now).build(); - let mut decorators = BasicMessageDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(now); + let decorators = BasicMessageDecorators::builder() + .timing(Timing::builder().out_time(now).build()) + .build(); - decorators.timing = Some(timing); - - BasicMessage::with_decorators(Uuid::new_v4().to_string(), content, decorators) + BasicMessage::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .decorators(decorators) + .build() } async fn decrypt_message( diff --git a/aries_vcx/tests/test_creds_proofs.rs b/aries_vcx/tests/test_creds_proofs.rs index e68f445665..fd4e287a0e 100644 --- a/aries_vcx/tests/test_creds_proofs.rs +++ b/aries_vcx/tests/test_creds_proofs.rs @@ -24,6 +24,8 @@ use aries_vcx::utils::constants::DEFAULT_SCHEMA_ATTRS; use aries_vcx::utils::devsetup::SetupProfile; use aries_vcx::utils::devsetup::*; +use messages::decorators::attachment::{Attachment, AttachmentData, AttachmentType}; +use messages::misc::MimeType; use messages::msg_fields::protocols::present_proof::request::{ RequestPresentation, RequestPresentationContent, RequestPresentationDecorators, }; @@ -72,17 +74,19 @@ async fn test_agency_pool_retrieve_credentials() { let pres_req_data: PresentationRequestData = serde_json::from_str(&req).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); let retrieved_creds = proof @@ -138,19 +142,21 @@ async fn test_agency_pool_retrieve_credentials_empty() { let pres_req_data: PresentationRequestData = serde_json::from_str(&req.to_string()).unwrap(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); // test retrieving credentials for empty proof request returns "{}" let id = "test_id".to_owned(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); #[cfg(feature = "migration")] @@ -167,19 +173,21 @@ async fn test_agency_pool_retrieve_credentials_empty() { req["requested_attributes"]["address1_1"] = json!({"name": "address1"}); let pres_req_data: PresentationRequestData = serde_json::from_str(&req.to_string()).unwrap(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); // test retrieving credentials for the proof request returns the referent with no cred matches let id = "test_id".to_owned(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("2", proof_req).unwrap(); let retrieved_creds = proof @@ -230,17 +238,19 @@ async fn test_agency_pool_case_for_proof_req_doesnt_matter_for_retrieve_creds() let pres_req_data: PresentationRequestData = serde_json::from_str(&req.to_string()).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); // All lower case @@ -258,20 +268,22 @@ async fn test_agency_pool_case_for_proof_req_doesnt_matter_for_retrieve_creds() let pres_req_data: PresentationRequestData = serde_json::from_str(&req.to_string()).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); #[cfg(feature = "migration")] setup.migrate().await; - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("2", proof_req).unwrap(); let retrieved_creds2 = proof .retrieve_credentials(&setup.profile.inject_anoncreds()) @@ -289,17 +301,20 @@ async fn test_agency_pool_case_for_proof_req_doesnt_matter_for_retrieve_creds() let pres_req_data: PresentationRequestData = serde_json::from_str(&req.to_string()).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); - - let content = RequestPresentationContent::new(vec![attach]); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); + + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); let decorators = RequestPresentationDecorators::default(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); let retrieved_creds3 = proof .retrieve_credentials(&setup.profile.inject_anoncreds()) @@ -355,17 +370,20 @@ async fn test_agency_pool_generate_proof() { let pres_req_data: PresentationRequestData = serde_json::from_str(&indy_proof_req).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); - - let content = RequestPresentationContent::new(vec![attach]); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); + + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); let decorators = RequestPresentationDecorators::default(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let mut proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); let all_creds = proof @@ -442,17 +460,19 @@ async fn test_agency_pool_generate_proof_with_predicates() { let pres_req_data: PresentationRequestData = serde_json::from_str(&indy_proof_req).unwrap(); let id = "test_id".to_owned(); - let attach_type = - messages::decorators::attachment::AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); - let attach_data = messages::decorators::attachment::AttachmentData::new(attach_type); - let mut attach = messages::decorators::attachment::Attachment::new(attach_data); - attach.id = Some(AttachmentId::PresentationRequest.as_ref().to_owned()); - attach.mime_type = Some(messages::misc::MimeType::Json); + let attach_type = AttachmentType::Base64(base64::encode(&json!(pres_req_data).to_string())); + let attach_data = AttachmentData::builder().content(attach_type).build(); + let attach = Attachment::builder() + .data(attach_data) + .id(AttachmentId::PresentationRequest.as_ref().to_owned()) + .mime_type(MimeType::Json) + .build(); - let content = RequestPresentationContent::new(vec![attach]); - let decorators = RequestPresentationDecorators::default(); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![attach]) + .build(); - let proof_req = RequestPresentation::with_decorators(id, content, decorators); + let proof_req = RequestPresentation::builder().id(id).content(content).build(); let mut proof: Prover = Prover::create_from_request("1", proof_req).unwrap(); #[cfg(feature = "migration")] @@ -741,7 +761,7 @@ async fn test_agency_pool_it_should_select_credentials_for_satisfiable_restricti let mut prover = create_prover_from_request(presentation_request.clone()).await; let selected_credentials = prover_select_credentials(&mut prover, &mut consumer, presentation_request.into(), None).await; - assert_eq!(selected_credentials.credential_for_referent.is_empty(), false); + assert!(!selected_credentials.credential_for_referent.is_empty()); }) .await; } @@ -960,7 +980,6 @@ async fn test_agency_pool_real_proof() { create_proof_request_data(&mut institution, &requested_attrs, "[]", "{}", None).await; let verifier = create_verifier_from_request_data(presentation_request_data).await; let presentation_request = verifier.get_presentation_request_msg().unwrap(); - let presentation_thread_id = verifier.get_thread_id().unwrap(); info!("test_real_proof :: Going to create proof"); prover_select_credentials_and_send_proof(&mut consumer, presentation_request, None).await; @@ -1249,7 +1268,6 @@ async fn test_agency_pool_presentation_via_proposal_with_negotiation() { #[cfg(feature = "migration")] consumer.migrate().await; - let presentation_proposal = create_proof_proposal(&mut prover, &cred_def_id).await; let presentation_request = accept_proof_proposal(&mut institution, &mut verifier, presentation_proposal).await; let selected_credentials = prover_select_credentials(&mut prover, &mut consumer, presentation_request, None).await; diff --git a/aries_vcx/tests/utils/scenarios.rs b/aries_vcx/tests/utils/scenarios.rs index da6956a625..920f5b3865 100644 --- a/aries_vcx/tests/utils/scenarios.rs +++ b/aries_vcx/tests/utils/scenarios.rs @@ -17,14 +17,9 @@ use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use aries_vcx::transport::Transport; use async_trait::async_trait; use messages::misc::MimeType; -use messages::msg_fields::protocols::connection::invitation::{ - Invitation, PairwiseInvitation, PairwiseInvitationContent, PublicInvitation, PublicInvitationContent, - PwInvitationDecorators, -}; +use messages::msg_fields::protocols::connection::invitation::{Invitation, InvitationContent}; use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential; -use messages::msg_fields::protocols::cred_issuance::propose_credential::{ - ProposeCredential, ProposeCredentialContent, ProposeCredentialDecorators, -}; +use messages::msg_fields::protocols::cred_issuance::propose_credential::{ProposeCredential, ProposeCredentialContent}; use messages::msg_fields::protocols::cred_issuance::{CredentialAttr, CredentialIssuance, CredentialPreview}; use messages::msg_fields::protocols::out_of_band::invitation::OobService; use messages::msg_fields::protocols::out_of_band::OobGoalCode; @@ -123,25 +118,35 @@ pub fn requested_attrs(did: &str, schema_id: &str, cred_def_id: &str, from: Opti pub fn requested_attr_objects(cred_def_id: &str) -> Vec { let (address1, address2, city, state, zip) = attr_names(); - let mut address1_attr = PresentationAttr::new(address1); - address1_attr.cred_def_id = Some(cred_def_id.to_owned()); - address1_attr.value = Some("123 Main St".to_owned()); - - let mut address2_attr = PresentationAttr::new(address2); - address2_attr.cred_def_id = Some(cred_def_id.to_owned()); - address2_attr.value = Some("Suite 3".to_owned()); - - let mut city_attr = PresentationAttr::new(city); - city_attr.cred_def_id = Some(cred_def_id.to_owned()); - city_attr.value = Some("Draper".to_owned()); - - let mut state_attr = PresentationAttr::new(state); - state_attr.cred_def_id = Some(cred_def_id.to_owned()); - state_attr.value = Some("UT".to_owned()); - - let mut zip_attr = PresentationAttr::new(zip); - zip_attr.cred_def_id = Some(cred_def_id.to_owned()); - zip_attr.value = Some("84000".to_owned()); + let address1_attr = PresentationAttr::builder() + .name(address1) + .cred_def_id(cred_def_id.to_owned()) + .value("123 Main St".to_owned()) + .build(); + + let address2_attr = PresentationAttr::builder() + .name(address2) + .cred_def_id(cred_def_id.to_owned()) + .value("Suite 3".to_owned()) + .build(); + + let city_attr = PresentationAttr::builder() + .name(city) + .cred_def_id(cred_def_id.to_owned()) + .value("Draper".to_owned()) + .build(); + + let state_attr = PresentationAttr::builder() + .name(state) + .cred_def_id(cred_def_id.to_owned()) + .value("UT".to_owned()) + .build(); + + let zip_attr = PresentationAttr::builder() + .name(zip) + .cred_def_id(cred_def_id.to_owned()) + .value("84000".to_owned()) + .build(); vec![address1_attr, address2_attr, city_attr, state_attr, zip_attr] } @@ -256,34 +261,52 @@ pub async fn create_credential_proposal(schema_id: &str, cred_def_id: &str, comm let (address1, address2, city, state, zip) = attr_names(); let mut attrs = Vec::new(); - let mut attr = CredentialAttr::new(address1, "123 Main Str".to_owned()); - attr.mime_type = Some(MimeType::Plain); + let attr = CredentialAttr::builder() + .name(address1) + .value("123 Main Str".to_owned()) + .mime_type(MimeType::Plain) + .build(); + attrs.push(attr); - let mut attr = CredentialAttr::new(address2, "Suite 3".to_owned()); - attr.mime_type = Some(MimeType::Plain); + let attr = CredentialAttr::builder() + .name(address2) + .value("Suite 3".to_owned()) + .mime_type(MimeType::Plain) + .build(); attrs.push(attr); - let mut attr = CredentialAttr::new(city, "Draper".to_owned()); - attr.mime_type = Some(MimeType::Plain); + let attr = CredentialAttr::builder() + .name(city) + .value("Draper".to_owned()) + .mime_type(MimeType::Plain) + .build(); attrs.push(attr); - let mut attr = CredentialAttr::new(state, "UT".to_owned()); - attr.mime_type = Some(MimeType::Plain); + let attr = CredentialAttr::builder() + .name(state) + .value("UT".to_owned()) + .mime_type(MimeType::Plain) + .build(); attrs.push(attr); - let mut attr = CredentialAttr::new(zip, "84000".to_owned()); - attr.mime_type = Some(MimeType::Plain); + let attr = CredentialAttr::builder() + .name(zip) + .value("84000".to_owned()) + .mime_type(MimeType::Plain) + .build(); attrs.push(attr); let preview = CredentialPreview::new(attrs); - let mut content = ProposeCredentialContent::new(preview, schema_id.to_owned(), cred_def_id.to_owned()); - content.comment = Some(comment.to_owned()); - - let decorators = ProposeCredentialDecorators::default(); + let content = ProposeCredentialContent::builder() + .credential_proposal(preview) + .schema_id(schema_id.to_owned()) + .cred_def_id(cred_def_id.to_owned()) + .comment(comment.to_owned()) + .build(); let id = "test".to_owned(); - ProposeCredential::with_decorators(id, content, decorators) + ProposeCredential::builder().id(id).content(content).build() } pub async fn accept_credential_proposal( @@ -977,11 +1000,17 @@ pub async fn create_connections_via_public_invite( alice: &mut TestAgent, faber: &mut TestAgent, ) -> (GenericConnection, GenericConnection) { - let content = PublicInvitationContent::new("faber".to_owned(), faber.institution_did.clone()); - let public_invite = AnyInvitation::Con(Invitation::Public(PublicInvitation::new( - "test_invite_id".to_owned(), - content, - ))); + let content = InvitationContent::builder_public() + .label("faber".to_owned()) + .did(faber.institution_did.clone()) + .build(); + + let public_invite = AnyInvitation::Con( + Invitation::builder() + .id("test_invite_id".to_owned()) + .content(content) + .build(), + ); let ddo = into_did_doc(&alice.profile.inject_indy_ledger_read(), &public_invite) .await .unwrap(); @@ -1000,15 +1029,14 @@ pub async fn create_connections_via_pairwise_invite( let inviter_pairwise_info = PairwiseInfo::create(&faber.profile.inject_wallet()).await.unwrap(); let invite = { let id = Uuid::new_v4().to_string(); - let content = PairwiseInvitationContent::new( - "".to_string(), - vec![inviter_pairwise_info.pw_vk.clone()], - vec![], - "http://dummy.org".parse().unwrap(), - ); - let decorators = PwInvitationDecorators::default(); - let invite = PairwiseInvitation::with_decorators(id, content, decorators); - AnyInvitation::Con(Invitation::Pairwise(invite)) + let content = InvitationContent::builder_pairwise() + .label("".to_string()) + .recipient_keys(vec![inviter_pairwise_info.pw_vk.clone()]) + .service_endpoint("http://dummy.org".parse().unwrap()) + .build(); + + let invite = Invitation::builder().id(id).content(content).build(); + AnyInvitation::Con(invite) }; establish_connection_from_invite(alice, faber, invite, inviter_pairwise_info).await diff --git a/libvcx_core/src/api_vcx/api_handle/mediated_connection.rs b/libvcx_core/src/api_vcx/api_handle/mediated_connection.rs index 52bf7268c5..e1c9084e91 100644 --- a/libvcx_core/src/api_vcx/api_handle/mediated_connection.rs +++ b/libvcx_core/src/api_vcx/api_handle/mediated_connection.rs @@ -1,9 +1,7 @@ use std::collections::HashMap; use aries_vcx::handlers::util::AnyInvitation; -use aries_vcx::messages::msg_fields::protocols::connection::invitation::{ - Invitation, PublicInvitation, PublicInvitationContent, -}; +use aries_vcx::messages::msg_fields::protocols::connection::invitation::{Invitation, InvitationContent}; use aries_vcx::messages::msg_fields::protocols::connection::request::Request; use aries_vcx::messages::AriesMessage; use serde_json; @@ -34,8 +32,14 @@ pub fn generate_public_invitation(public_did: &str, label: &str) -> LibvcxResult public_did, label ); - let content = PublicInvitationContent::new(label.to_owned(), public_did.to_owned()); - let invite = PublicInvitation::new(Uuid::new_v4().to_string(), content); + let content = InvitationContent::builder_public() + .label(label.to_owned()) + .did(public_did.to_owned()) + .build(); + let invite: Invitation = Invitation::builder() + .id(Uuid::new_v4().to_string()) + .content(content) + .build(); let invitation = AriesMessage::from(invite); Ok(json!(invitation).to_string()) @@ -254,13 +258,7 @@ pub async fn connect(handle: u32) -> LibvcxResult> { .connect(&get_main_wallet()?, &get_main_agency_client()?, None) .await?; let invitation = connection.get_invite_details().map(|invitation| match invitation { - AnyInvitation::Con(Invitation::Pairwise(invitation)) => { - json!(AriesMessage::from(invitation.clone())).to_string() - } - AnyInvitation::Con(Invitation::PairwiseDID(invitation)) => { - json!(AriesMessage::from(invitation.clone())).to_string() - } - AnyInvitation::Con(Invitation::Public(invitation)) => json!(AriesMessage::from(invitation.clone())).to_string(), + AnyInvitation::Con(invitation) => json!(AriesMessage::from(invitation.clone())).to_string(), AnyInvitation::Oob(invitation) => json!(AriesMessage::from(invitation.clone())).to_string(), }); CONNECTION_MAP.insert(handle, connection)?; @@ -292,15 +290,7 @@ pub fn get_invite_details(handle: u32) -> LibvcxResult { connection .get_invite_details() .map(|invitation| match invitation { - AnyInvitation::Con(Invitation::Pairwise(invitation)) => { - json!(AriesMessage::from(invitation.clone())).to_string() - } - AnyInvitation::Con(Invitation::PairwiseDID(invitation)) => { - json!(AriesMessage::from(invitation.clone())).to_string() - } - AnyInvitation::Con(Invitation::Public(invitation)) => { - json!(AriesMessage::from(invitation.clone())).to_string() - } + AnyInvitation::Con(invitation) => json!(AriesMessage::from(invitation.clone())).to_string(), AnyInvitation::Oob(invitation) => json!(AriesMessage::from(invitation.clone())).to_string(), }) .ok_or(LibvcxError::from_msg( @@ -487,9 +477,7 @@ pub mod test_utils { #[cfg(test)] pub mod tests { - use aries_vcx::messages::msg_fields::protocols::connection::invitation::{ - PairwiseInvitation, PairwiseInvitationContent, PwInvitationDecorators, - }; + use aries_vcx::messages::msg_fields::protocols::connection::invitation::InvitationContent; use serde_json::Value; use aries_vcx; @@ -537,10 +525,14 @@ pub mod tests { let _setup = SetupMocks::init(); let id = Uuid::new_v4().to_string(); - let content = PairwiseInvitationContent::new(_label(), _recipient_keys(), _routing_keys(), _service_endpoint()); - let decorators = PwInvitationDecorators::default(); + let content = InvitationContent::builder_pairwise() + .label(_label()) + .recipient_keys(_recipient_keys()) + .routing_keys(_routing_keys()) + .service_endpoint(_service_endpoint()) + .build(); - let msg = AriesMessage::from(PairwiseInvitation::with_decorators(id, content, decorators)); + let msg: AriesMessage = Invitation::builder().id(id).content(content).build(); let connection_handle = mediated_connection::create_connection_with_invite(_source_id(), &serde_json::to_string(&msg).unwrap()) @@ -555,9 +547,9 @@ pub mod tests { let _setup = SetupMocks::init(); let id = Uuid::new_v4().to_string(); - let content = PublicInvitationContent::new(_label(), _did()); - - let msg = AriesMessage::from(PublicInvitation::new(id, content)); + let content = InvitationContent::builder_public().label(_label()).did(_did()).build(); + let invitation: Invitation = Invitation::builder().id(id).content(content).build(); + let msg = AriesMessage::from(invitation); let connection_handle = mediated_connection::create_connection_with_invite(_source_id(), &serde_json::to_string(&msg).unwrap()) diff --git a/messages/Cargo.toml b/messages/Cargo.toml index 286a66f804..21dd89d643 100644 --- a/messages/Cargo.toml +++ b/messages/Cargo.toml @@ -20,6 +20,8 @@ thiserror = "1.0.37" derive_more = "0.99.17" transitive = "0.5.0" isolang = { version = "2.2.0" } +typed-builder = "0.16.0" messages_macros = { path = "../messages_macros" } diddoc_legacy = { path = "../diddoc_legacy" } shared_vcx = { path = "../shared_vcx" } +did_parser = { path = "../did_parser" } diff --git a/messages/src/decorators/attachment.rs b/messages/src/decorators/attachment.rs index 79f6d69998..203a39ba32 100644 --- a/messages/src/decorators/attachment.rs +++ b/messages/src/decorators/attachment.rs @@ -1,67 +1,52 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_json::Value; +use typed_builder::TypedBuilder; use url::Url; use crate::misc::MimeType; /// Struct representing the `~attach` decorator from its [RFC](). -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TypedBuilder)] #[serde(rename_all = "snake_case")] pub struct Attachment { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "@id")] pub id: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub filename: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "mime-type")] pub mime_type: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub lastmod_time: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub byte_count: Option, pub data: AttachmentData, } -impl Attachment { - pub fn new(data: AttachmentData) -> Self { - Self { - id: None, - description: None, - filename: None, - mime_type: None, - lastmod_time: None, - byte_count: None, - data, - } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypedBuilder)] pub struct AttachmentData { // There probably is a better type for this??? + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub jws: Option, // Better type for this as well? + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub sha256: Option, #[serde(flatten)] pub content: AttachmentType, } -impl AttachmentData { - pub fn new(content: AttachmentType) -> Self { - Self { - jws: None, - sha256: None, - content, - } - } -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "lowercase")] pub enum AttachmentType { @@ -88,8 +73,8 @@ pub mod tests { }); let content = AttachmentType::Json(data); - let attach_data = AttachmentData::new(content); - Attachment::new(attach_data) + let attach_data = AttachmentData::builder().content(content).build(); + Attachment::builder().data(attach_data).build() } pub fn make_extended_attachment() -> Attachment { @@ -98,23 +83,16 @@ pub mod tests { }); let content = AttachmentType::Json(data); - let attach_data = AttachmentData::new(content); - let mut attachment = Attachment::new(attach_data); - let id = "test_id".to_owned(); - let description = "test_description".to_owned(); - let filename = "test_filename".to_owned(); - let mime_type = MimeType::Json; - let lastmod_time = DateTime::::default(); - let byte_count = 64; - - attachment.id = Some(id); - attachment.description = Some(description); - attachment.filename = Some(filename); - attachment.mime_type = Some(mime_type); - attachment.lastmod_time = Some(lastmod_time); - attachment.byte_count = Some(byte_count); - - attachment + let attach_data = AttachmentData::builder().content(content).build(); + Attachment::builder() + .data(attach_data) + .id("test_id".to_owned()) + .description("test_description".to_owned()) + .filename("test_filename".to_owned()) + .mime_type(MimeType::Json) + .lastmod_time(DateTime::::default()) + .byte_count(64) + .build() } #[test] @@ -158,7 +136,7 @@ pub mod tests { let expected = json!({ "json": data }); let content = AttachmentType::Json(data); - let attach_data = AttachmentData::new(content); + let attach_data = AttachmentData::builder().content(content).build(); test_utils::test_serde(attach_data, expected); } @@ -179,9 +157,11 @@ pub mod tests { }); let content = AttachmentType::Json(data); - let mut attach_data = AttachmentData::new(content); - attach_data.jws = Some(jws); - attach_data.sha256 = Some(sha256); + let attach_data = AttachmentData::builder() + .content(content) + .jws(jws) + .sha256(sha256) + .build(); test_utils::test_serde(attach_data, expected); } diff --git a/messages/src/decorators/localization.rs b/messages/src/decorators/localization.rs index 1ed30e8b49..a817d7252c 100644 --- a/messages/src/decorators/localization.rs +++ b/messages/src/decorators/localization.rs @@ -6,29 +6,36 @@ use serde::{ Deserialize, Serialize, Serializer, }; use shared_vcx::misc::utils::CowStr; +use typed_builder::TypedBuilder; use url::Url; /// Struct representing the `~l10n` decorator, when it decorates the entire message, from its [RFC](). -#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, TypedBuilder)] pub struct MsgLocalization { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub catalogs: Option>, // Might just be obsolete, but appears in // Is details and locales the same thing? + #[builder(default, setter(strip_option))] #[serde(alias = "details")] #[serde(skip_serializing_if = "Option::is_none")] pub locales: Option>>, } /// Struct representing the `~l10n` decorator, when it decorates a single field, from its [RFC](). -#[derive(Debug, Clone, Deserialize, Default, PartialEq)] +#[derive(Debug, Clone, Deserialize, Default, PartialEq, TypedBuilder)] pub struct FieldLocalization { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub code: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub locale: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub catalogs: Option>, + #[builder(default)] #[serde(flatten)] #[serde(skip_serializing_if = "HashMap::is_empty")] pub translations: HashMap, @@ -127,13 +134,12 @@ pub mod tests { let catalogs = vec!["https://dummy.dummy/dummy".parse().unwrap()]; let translations = HashMap::from([(Locale(Language::Fra), "test, but in french".to_owned())]); - let mut localization = FieldLocalization::default(); - localization.code = Some(code); - localization.locale = Some(locale); - localization.catalogs = Some(catalogs); - localization.translations = translations; - - localization + FieldLocalization::builder() + .code(code) + .locale(locale) + .catalogs(catalogs) + .translations(translations) + .build() } pub fn make_minimal_msg_localization() -> MsgLocalization { @@ -144,11 +150,7 @@ pub mod tests { let catalogs = vec!["https://dummy.dummy/dummy".parse().unwrap()]; let locales = HashMap::from([(Locale(Language::Fra), vec!["test, but in french".to_owned()])]); - let mut localization = MsgLocalization::default(); - localization.catalogs = Some(catalogs); - localization.locales = Some(locales); - - localization + MsgLocalization::builder().catalogs(catalogs).locales(locales).build() } #[test] diff --git a/messages/src/decorators/please_ack.rs b/messages/src/decorators/please_ack.rs index 491ea46bc0..41bcfb207d 100644 --- a/messages/src/decorators/please_ack.rs +++ b/messages/src/decorators/please_ack.rs @@ -1,7 +1,8 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; /// Struct representing the `~please_ack` decorators from its [RFC](). -#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, TypedBuilder)] pub struct PleaseAck { // This is wrong, but necessary for backwards compatibility. // Per the [RFC]() @@ -17,12 +18,6 @@ pub struct PleaseAck { pub on: Vec, } -impl PleaseAck { - pub fn new(on: Vec) -> Self { - Self { on } - } -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "UPPERCASE")] pub enum AckOn { @@ -41,7 +36,7 @@ pub mod tests { pub fn make_minimal_please_ack() -> PleaseAck { let on = vec![AckOn::Receipt, AckOn::Outcome]; - PleaseAck::new(on) + PleaseAck::builder().on(on).build() } #[test] diff --git a/messages/src/decorators/thread.rs b/messages/src/decorators/thread.rs index 4ca939d073..6768e32cd0 100644 --- a/messages/src/decorators/thread.rs +++ b/messages/src/decorators/thread.rs @@ -2,33 +2,26 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; /// Struct representing the `~thread` decorator from its [RFC](). -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct Thread { pub thid: String, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub pthid: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub sender_order: Option, + #[builder(default, setter(strip_option))] #[serde(default, skip_serializing_if = "Option::is_none")] pub received_orders: Option>, // should get replaced with DID. + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub goal_code: Option>, } -impl Thread { - pub fn new(thid: String) -> Self { - Self { - thid, - pthid: None, - sender_order: None, - received_orders: None, - goal_code: None, - } - } -} - #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub enum ThreadGoalCode { #[serde(rename = "aries.vc")] @@ -56,24 +49,23 @@ pub mod tests { pub fn make_minimal_thread() -> Thread { let thid = "test".to_owned(); - Thread::new(thid) + Thread::builder().thid(thid).build() } pub fn make_extended_thread() -> Thread { let thid = "test".to_owned(); - let mut thread = Thread::new(thid); - let pthid = "test_pthid".to_owned(); let sender_order = 5; let received_orders = HashMap::from([("a".to_owned(), 1), ("b".to_owned(), 2), ("c".to_owned(), 3)]); let goal_code = MaybeKnown::Known(ThreadGoalCode::AriesVcVerify); - thread.pthid = Some(pthid); - thread.sender_order = Some(sender_order); - thread.received_orders = Some(received_orders); - thread.goal_code = Some(goal_code); - - thread + Thread::builder() + .thid(thid) + .pthid(pthid) + .sender_order(sender_order) + .received_orders(received_orders) + .goal_code(goal_code) + .build() } #[test] diff --git a/messages/src/decorators/timing.rs b/messages/src/decorators/timing.rs index 08b377c311..c2a4477cf6 100644 --- a/messages/src/decorators/timing.rs +++ b/messages/src/decorators/timing.rs @@ -1,24 +1,31 @@ use crate::misc::utils; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; /// Struct representing the `~timing` decorator from its [RFC](). -#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq)] +#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq, TypedBuilder)] pub struct Timing { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "utils::serialize_opt_datetime")] pub in_time: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "utils::serialize_opt_datetime")] pub out_time: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "utils::serialize_opt_datetime")] pub stale_time: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "utils::serialize_opt_datetime")] pub expires_time: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub delay_milli: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "utils::serialize_opt_datetime")] pub wait_until_time: Option>, @@ -41,15 +48,14 @@ pub mod tests { let dt = DateTime::default(); let delay_milli = 10; - let mut timing = Timing::default(); - timing.in_time = Some(dt); - timing.out_time = Some(dt); - timing.stale_time = Some(dt); - timing.expires_time = Some(dt); - timing.delay_milli = Some(delay_milli); - timing.wait_until_time = Some(dt); - - timing + Timing::builder() + .in_time(dt) + .out_time(dt) + .stale_time(dt) + .expires_time(dt) + .delay_milli(delay_milli) + .wait_until_time(dt) + .build() } #[test] diff --git a/messages/src/misc/mod.rs b/messages/src/misc/mod.rs index 3e4fa4a3eb..3d2e0501e6 100644 --- a/messages/src/misc/mod.rs +++ b/messages/src/misc/mod.rs @@ -84,7 +84,11 @@ pub mod test_utils { obj.insert("@id".to_owned(), json!(id)); obj.insert("@type".to_owned(), json!(msg_type)); - let msg = MsgParts::with_decorators(id, content, decorators); + let msg = MsgParts::::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); let msg = AriesMessage::from(msg); test_serde(msg, expected); diff --git a/messages/src/msg_fields/protocols/basic_message.rs b/messages/src/msg_fields/protocols/basic_message.rs index 488670ceb7..b3c66565c5 100644 --- a/messages/src/msg_fields/protocols/basic_message.rs +++ b/messages/src/msg_fields/protocols/basic_message.rs @@ -3,6 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{localization::MsgLocalization, thread::Thread, timing::Timing}, @@ -13,27 +14,24 @@ use crate::{ pub type BasicMessage = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct BasicMessageContent { pub content: String, #[serde(serialize_with = "utils::serialize_datetime")] pub sent_time: DateTime, } -impl BasicMessageContent { - pub fn new(content: String, sent_time: DateTime) -> Self { - Self { content, sent_time } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct BasicMessageDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~l10n")] #[serde(skip_serializing_if = "Option::is_none")] pub l10n: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -55,7 +53,10 @@ mod tests { #[test] fn test_minimal_basic_message() { - let content = BasicMessageContent::new("test_content".to_owned(), DateTime::default()); + let content = BasicMessageContent::builder() + .content("test_content".to_owned()) + .sent_time(DateTime::default()) + .build(); let decorators = BasicMessageDecorators::default(); @@ -69,10 +70,12 @@ mod tests { #[test] fn test_extended_basic_message() { - let content = BasicMessageContent::new("test_content".to_owned(), DateTime::default()); + let content = BasicMessageContent::builder() + .content("test_content".to_owned()) + .sent_time(DateTime::default()) + .build(); - let mut decorators = BasicMessageDecorators::default(); - decorators.thread = Some(make_extended_thread()); + let decorators = BasicMessageDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "sent_time": DateTimeRfc3339(&content.sent_time), diff --git a/messages/src/msg_fields/protocols/connection/invitation/mod.rs b/messages/src/msg_fields/protocols/connection/invitation/mod.rs index 6ab58acb8e..783817ce3f 100644 --- a/messages/src/msg_fields/protocols/connection/invitation/mod.rs +++ b/messages/src/msg_fields/protocols/connection/invitation/mod.rs @@ -2,38 +2,50 @@ pub mod pairwise; pub mod public; use derive_more::From; +use did_parser::Did; use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use url::Url; +use self::{pairwise::PwInvitationContentBuilder, public::PublicInvitationContentBuilder}; pub use self::{ - pairwise::{PairwiseDidInvitation, PairwiseInvitation, PairwiseInvitationContent, PwInvitationDecorators}, - public::{PublicInvitation, PublicInvitationContent}, + pairwise::{PairwiseDidInvitationContent, PairwiseInvitationContent}, + public::PublicInvitationContent, }; -use super::Connection; -use crate::misc::utils::transit_to_aries_msg; +use crate::{decorators::timing::Timing, msg_parts::MsgParts}; + +pub type Invitation = MsgParts; /// We need another level of enum nesting since /// an invitation can have multiple forms, and this way we /// take advantage of `untagged` deserialization. #[derive(Debug, Clone, From, Deserialize, Serialize, PartialEq)] #[serde(untagged)] -pub enum Invitation { - Public(PublicInvitation), - Pairwise(PairwiseInvitation), - PairwiseDID(PairwiseDidInvitation), +pub enum InvitationContent { + Public(PublicInvitationContent), + PairwiseDID(PairwiseDidInvitationContent), + Pairwise(PairwiseInvitationContent), } -impl Invitation { - pub fn id(&self) -> &str { - match self { - Invitation::Public(invitation) => &invitation.id, - Invitation::Pairwise(invitation) => &invitation.id, - Invitation::PairwiseDID(invitation) => &invitation.id, - } +impl InvitationContent { + pub fn builder_public() -> PublicInvitationContentBuilder { + PublicInvitationContent::builder() + } + + pub fn builder_pairwise() -> PwInvitationContentBuilder { + PairwiseInvitationContent::builder() + } + + pub fn builder_pairwise_did() -> PwInvitationContentBuilder { + PairwiseDidInvitationContent::builder() } } -transit_to_aries_msg!(PublicInvitationContent, Invitation, Connection); -transit_to_aries_msg!(PairwiseInvitationContent:PwInvitationDecorators, Invitation, Connection); -transit_to_aries_msg!(PairwiseInvitationContent:PwInvitationDecorators, Invitation, Connection); +#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct InvitationDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~timing")] + #[serde(skip_serializing_if = "Option::is_none")] + pub timing: Option, +} diff --git a/messages/src/msg_fields/protocols/connection/invitation/pairwise.rs b/messages/src/msg_fields/protocols/connection/invitation/pairwise.rs index 0577997126..6d92c087fc 100644 --- a/messages/src/msg_fields/protocols/connection/invitation/pairwise.rs +++ b/messages/src/msg_fields/protocols/connection/invitation/pairwise.rs @@ -1,39 +1,38 @@ +use did_parser::Did; use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use url::Url; -use crate::{decorators::timing::Timing, msg_parts::MsgParts}; +use super::InvitationContent; -pub type PairwiseInvitation = MsgParts, PwInvitationDecorators>; -pub type PairwiseDidInvitation = MsgParts, PwInvitationDecorators>; +pub type PairwiseInvitationContent = PwInvitationContent; +pub type PairwiseDidInvitationContent = PwInvitationContent; -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(rename_all = "camelCase")] -pub struct PairwiseInvitationContent { +#[builder(build_method(vis="", name=__build))] +#[builder(builder_type(vis = "pub"))] +pub struct PwInvitationContent { pub label: String, pub recipient_keys: Vec, + #[builder(default)] #[serde(default)] pub routing_keys: Vec, pub service_endpoint: T, } -impl PairwiseInvitationContent { - pub fn new(label: String, recipient_keys: Vec, routing_keys: Vec, service_endpoint: T) -> Self { - Self { - label, - recipient_keys, - routing_keys, - service_endpoint, - } +#[allow(dead_code, non_camel_case_types, missing_docs)] +impl>> + PwInvitationContentBuilder,), __routing_keys, (T,))> +where + PwInvitationContent: Into, +{ + #[allow(clippy::default_trait_access)] + pub fn build(self) -> InvitationContent { + self.__build().into() } } -#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)] -pub struct PwInvitationDecorators { - #[serde(rename = "~timing")] - #[serde(skip_serializing_if = "Option::is_none")] - pub timing: Option, -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -42,25 +41,29 @@ mod tests { use super::*; use crate::{ - decorators::timing::tests::make_extended_timing, misc::test_utils, msg_types::connection::ConnectionTypeV1_0, + decorators::timing::tests::make_extended_timing, misc::test_utils, + msg_fields::protocols::connection::invitation::InvitationDecorators, msg_types::connection::ConnectionTypeV1_0, }; #[test] fn test_minimal_conn_invite_pw() { - let content = PairwiseInvitationContent::new( - "test_pw_invite_label".to_owned(), - vec!["test_recipient_key".to_owned()], - vec![], - Url::parse("https://dummy.dummy/dummy").unwrap(), - ); + let label = "test_pw_invite_label"; + let recipient_keys = vec!["test_recipient_key".to_owned()]; + let service_endpoint = "https://dummy.dummy/dummy"; + + let content = InvitationContent::builder_pairwise() + .label(label.to_owned()) + .recipient_keys(recipient_keys.clone()) + .service_endpoint(service_endpoint.parse().unwrap()) + .build(); - let decorators = PwInvitationDecorators::default(); + let decorators = InvitationDecorators::default(); let expected = json!({ - "label": content.label, - "recipientKeys": content.recipient_keys, - "routingKeys": content.routing_keys, - "serviceEndpoint": content.service_endpoint, + "label": label, + "recipientKeys": recipient_keys, + "routingKeys": [], + "serviceEndpoint": service_endpoint, }); test_utils::test_msg(content, decorators, ConnectionTypeV1_0::Invitation, expected); @@ -68,21 +71,25 @@ mod tests { #[test] fn test_extended_conn_invite_pw() { - let content = PairwiseInvitationContent::new( - "test_pw_invite_label".to_owned(), - vec!["test_recipient_key".to_owned()], - vec!["test_routing_key".to_owned()], - Url::parse("https://dummy.dummy/dummy").unwrap(), - ); + let label = "test_pw_invite_label"; + let recipient_keys = vec!["test_recipient_key".to_owned()]; + let routing_keys = vec!["test_routing_key".to_owned()]; + let service_endpoint = "https://dummy.dummy/dummy"; - let mut decorators = PwInvitationDecorators::default(); - decorators.timing = Some(make_extended_timing()); + let content = InvitationContent::builder_pairwise() + .label(label.to_owned()) + .recipient_keys(recipient_keys.clone()) + .routing_keys(routing_keys.clone()) + .service_endpoint(service_endpoint.parse().unwrap()) + .build(); + + let decorators = InvitationDecorators::builder().timing(make_extended_timing()).build(); let expected = json!({ - "label": content.label, - "recipientKeys": content.recipient_keys, - "routingKeys": content.routing_keys, - "serviceEndpoint": content.service_endpoint, + "label": label, + "recipientKeys": recipient_keys, + "routingKeys": routing_keys, + "serviceEndpoint": service_endpoint, "~timing": decorators.timing }); @@ -91,20 +98,23 @@ mod tests { #[test] fn test_minimal_conn_invite_pw_did() { - let content = PairwiseInvitationContent::new( - "test_pw_invite_label".to_owned(), - vec!["test_recipient_key".to_owned()], - vec![], - "test_conn_invite_pw_did".to_owned(), - ); + let label = "test_pw_invite_label"; + let recipient_keys = vec!["test_recipient_key".to_owned()]; + let service_endpoint = "did:sov:123456789abcdefghi1234"; + + let content = InvitationContent::builder_pairwise_did() + .label(label.to_owned()) + .recipient_keys(recipient_keys.clone()) + .service_endpoint(service_endpoint.parse().unwrap()) + .build(); - let decorators = PwInvitationDecorators::default(); + let decorators = InvitationDecorators::default(); let expected = json!({ - "label": content.label, - "recipientKeys": content.recipient_keys, - "routingKeys": content.routing_keys, - "serviceEndpoint": content.service_endpoint, + "label": label, + "recipientKeys": recipient_keys, + "routingKeys": [], + "serviceEndpoint": service_endpoint, }); test_utils::test_msg(content, decorators, ConnectionTypeV1_0::Invitation, expected); @@ -112,21 +122,25 @@ mod tests { #[test] fn test_extended_conn_invite_pw_did() { - let content = PairwiseInvitationContent::new( - "test_pw_invite_label".to_owned(), - vec!["test_recipient_key".to_owned()], - vec!["test_routing_key".to_owned()], - "test_conn_invite_pw_did".to_owned(), - ); + let label = "test_pw_invite_label"; + let recipient_keys = vec!["test_recipient_key".to_owned()]; + let routing_keys = vec!["test_routing_key".to_owned()]; + let service_endpoint = "did:sov:123456789abcdefghi1234"; + + let content = InvitationContent::builder_pairwise_did() + .label(label.to_owned()) + .recipient_keys(recipient_keys.clone()) + .routing_keys(routing_keys.clone()) + .service_endpoint(service_endpoint.parse().unwrap()) + .build(); - let mut decorators = PwInvitationDecorators::default(); - decorators.timing = Some(make_extended_timing()); + let decorators = InvitationDecorators::builder().timing(make_extended_timing()).build(); let expected = json!({ - "label": content.label, - "recipientKeys": content.recipient_keys, - "routingKeys": content.routing_keys, - "serviceEndpoint": content.service_endpoint, + "label": label, + "recipientKeys": recipient_keys, + "routingKeys": routing_keys, + "serviceEndpoint": service_endpoint, "~timing": decorators.timing }); diff --git a/messages/src/msg_fields/protocols/connection/invitation/public.rs b/messages/src/msg_fields/protocols/connection/invitation/public.rs index 1d65d8d93c..23bc160e3b 100644 --- a/messages/src/msg_fields/protocols/connection/invitation/public.rs +++ b/messages/src/msg_fields/protocols/connection/invitation/public.rs @@ -1,21 +1,15 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; -use crate::msg_parts::MsgParts; +use super::InvitationContent; -pub type PublicInvitation = MsgParts; - -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, TypedBuilder)] +#[builder(build_method(into = InvitationContent))] pub struct PublicInvitationContent { pub label: String, pub did: String, } -impl PublicInvitationContent { - pub fn new(label: String, did: String) -> Self { - Self { label, did } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -23,20 +17,49 @@ mod tests { use serde_json::json; use super::*; - use crate::{misc::test_utils, msg_types::connection::ConnectionTypeV1_0}; - - // Bind `shared_vcx::misc::serde_ignored::SerdeIgnored` type as `NoDecorators`. - use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; + use crate::{ + decorators::timing::tests::make_extended_timing, misc::test_utils, + msg_fields::protocols::connection::invitation::InvitationDecorators, msg_types::connection::ConnectionTypeV1_0, + }; #[test] fn test_minimal_conn_invite_public() { - let content = PublicInvitationContent::new("test_label".to_owned(), "test_did".to_owned()); + let label = "test_label"; + let did = "test_did"; + + let content = InvitationContent::builder_public() + .label(label.to_owned()) + .did(did.to_owned()) + .build(); + + let expected = json!({ + "label": label, + "did": did + }); + + let decorators = InvitationDecorators::default(); + + test_utils::test_msg(content, decorators, ConnectionTypeV1_0::Invitation, expected); + } + + #[test] + fn test_extended_conn_invite_public() { + let label = "test_label"; + let did = "test_did"; + + let content = InvitationContent::builder_public() + .label(label.to_owned()) + .did(did.to_owned()) + .build(); + + let decorators = InvitationDecorators::builder().timing(make_extended_timing()).build(); let expected = json!({ - "label": content.label, - "did": content.did + "label": label, + "did": did, + "~timing": decorators.timing }); - test_utils::test_msg(content, NoDecorators, ConnectionTypeV1_0::Invitation, expected); + test_utils::test_msg(content, decorators, ConnectionTypeV1_0::Invitation, expected); } } diff --git a/messages/src/msg_fields/protocols/connection/mod.rs b/messages/src/msg_fields/protocols/connection/mod.rs index 114289a17e..5228b394dc 100644 --- a/messages/src/msg_fields/protocols/connection/mod.rs +++ b/messages/src/msg_fields/protocols/connection/mod.rs @@ -10,7 +10,7 @@ use diddoc_legacy::aries::diddoc::AriesDidDoc; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use self::{ - invitation::Invitation, + invitation::{Invitation, InvitationContent, InvitationDecorators}, problem_report::{ProblemReport, ProblemReportContent, ProblemReportDecorators}, request::{Request, RequestContent, RequestDecorators}, response::{Response, ResponseContent, ResponseDecorators}, @@ -80,6 +80,7 @@ impl ConnectionData { } } +transit_to_aries_msg!(InvitationContent: InvitationDecorators, Connection); transit_to_aries_msg!(RequestContent: RequestDecorators, Connection); transit_to_aries_msg!(ResponseContent: ResponseDecorators, Connection); transit_to_aries_msg!(ProblemReportContent: ProblemReportDecorators, Connection); diff --git a/messages/src/msg_fields/protocols/connection/problem_report.rs b/messages/src/msg_fields/protocols/connection/problem_report.rs index 09f72dd034..d442ae50ba 100644 --- a/messages/src/msg_fields/protocols/connection/problem_report.rs +++ b/messages/src/msg_fields/protocols/connection/problem_report.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{localization::MsgLocalization, thread::Thread, timing::Timing}, @@ -7,11 +8,13 @@ use crate::{ pub type ProblemReport = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct ProblemReportContent { + #[builder(default, setter(strip_option))] #[serde(rename = "problem-code")] #[serde(skip_serializing_if = "Option::is_none")] pub problem_code: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub explain: Option, } @@ -25,28 +28,20 @@ pub enum ProblemCode { ResponseProcessingError, } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ProblemReportDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~l10n")] #[serde(skip_serializing_if = "Option::is_none")] pub localization: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl ProblemReportDecorators { - pub fn new(thread: Thread) -> Self { - Self { - thread, - localization: None, - timing: None, - } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -67,7 +62,9 @@ mod tests { fn test_minimal_conn_problem_report() { let content = ProblemReportContent::default(); - let decorators = ProblemReportDecorators::new(make_extended_thread()); + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .build(); let expected = json!({ "~thread": decorators.thread @@ -78,13 +75,16 @@ mod tests { #[test] fn test_extended_conn_problem_report() { - let mut content = ProblemReportContent::default(); - content.problem_code = Some(ProblemCode::RequestNotAccepted); - content.explain = Some("test_conn_problem_report_explain".to_owned()); - - let mut decorators = ProblemReportDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); - decorators.localization = Some(make_extended_msg_localization()); + let content = ProblemReportContent::builder() + .problem_code(ProblemCode::RequestNotAccepted) + .explain("test_conn_problem_report_explain".to_owned()) + .build(); + + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .localization(make_extended_msg_localization()) + .build(); let expected = json!({ "problem-code": content.problem_code, diff --git a/messages/src/msg_fields/protocols/connection/request.rs b/messages/src/msg_fields/protocols/connection/request.rs index 9d7c9dde31..b6fc02cb58 100644 --- a/messages/src/msg_fields/protocols/connection/request.rs +++ b/messages/src/msg_fields/protocols/connection/request.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -9,23 +10,19 @@ use super::ConnectionData; pub type Request = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct RequestContent { pub label: String, pub connection: ConnectionData, } -impl RequestContent { - pub fn new(label: String, connection: ConnectionData) -> Self { - Self { label, connection } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct RequestDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -49,7 +46,10 @@ mod tests { fn test_minimal_conn_request() { let did_doc = AriesDidDoc::default(); // We really need to improve this creation. let conn_data = ConnectionData::new("test_did".to_owned(), did_doc); - let content = RequestContent::new("test_request_label".to_owned(), conn_data); + let content = RequestContent::builder() + .label("test_request_label".to_owned()) + .connection(conn_data) + .build(); let decorators = RequestDecorators::default(); @@ -65,11 +65,15 @@ mod tests { fn test_extended_conn_request() { let did_doc = AriesDidDoc::default(); // We really need to improve this creation. let conn_data = ConnectionData::new("test_did".to_owned(), did_doc); - let content = RequestContent::new("test_request_label".to_owned(), conn_data); - - let mut decorators = RequestDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let content = RequestContent::builder() + .label("test_request_label".to_owned()) + .connection(conn_data) + .build(); + + let decorators = RequestDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "label": content.label, diff --git a/messages/src/msg_fields/protocols/connection/response.rs b/messages/src/msg_fields/protocols/connection/response.rs index 68b82b6b62..e6e0c259f6 100644 --- a/messages/src/msg_fields/protocols/connection/response.rs +++ b/messages/src/msg_fields/protocols/connection/response.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use shared_vcx::misc::utils::CowStr; +use typed_builder::TypedBuilder; use crate::{ decorators::{please_ack::PleaseAck, thread::Thread, timing::Timing}, @@ -13,18 +14,12 @@ use crate::{ pub type Response = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ResponseContent { #[serde(rename = "connection~sig")] pub connection_sig: ConnectionSignature, } -impl ResponseContent { - pub fn new(connection_sig: ConnectionSignature) -> Self { - Self { connection_sig } - } -} - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct ConnectionSignature { #[serde(rename = "@type")] @@ -45,28 +40,20 @@ impl ConnectionSignature { } } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, TypedBuilder)] pub struct ResponseDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~please_ack")] #[serde(skip_serializing_if = "Option::is_none")] pub please_ack: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl ResponseDecorators { - pub fn new(thread: Thread) -> Self { - Self { - thread, - please_ack: None, - timing: None, - } - } -} - /// Non-standalone message type. /// This is only encountered as part of an existent message. /// It is not a message on it's own. @@ -131,9 +118,9 @@ mod tests { "test_signer".to_owned(), ); - let content = ResponseContent::new(conn_sig); + let content = ResponseContent::builder().connection_sig(conn_sig).build(); - let decorators = ResponseDecorators::new(make_extended_thread()); + let decorators = ResponseDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "connection~sig": content.connection_sig, @@ -151,11 +138,13 @@ mod tests { "test_signer".to_owned(), ); - let content = ResponseContent::new(conn_sig); + let content = ResponseContent::builder().connection_sig(conn_sig).build(); - let mut decorators = ResponseDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); - decorators.please_ack = Some(make_minimal_please_ack()); + let decorators = ResponseDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .please_ack(make_minimal_please_ack()) + .build(); let expected = json!({ "connection~sig": content.connection_sig, diff --git a/messages/src/msg_fields/protocols/cred_issuance/ack.rs b/messages/src/msg_fields/protocols/cred_issuance/ack.rs index 35c9042f12..ccdd2b3ab2 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/ack.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/ack.rs @@ -1,19 +1,32 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}, + msg_fields::protocols::notification::ack::{Ack, AckContent, AckDecorators}, msg_parts::MsgParts, }; pub type AckCredential = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct AckCredentialContent(pub AckContent); +pub struct AckCredentialContent { + pub inner: AckContent, +} + +impl From for AckCredentialContent { + fn from(value: AckContent) -> Self { + Self { inner: value } + } +} -impl AckCredentialContent { - pub fn new(status: AckStatus) -> Self { - Self(AckContent::new(status)) +impl From for Ack { + fn from(value: AckCredential) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() } } @@ -27,17 +40,18 @@ mod tests { use crate::{ decorators::{thread::tests::make_extended_thread, timing::tests::make_extended_timing}, misc::test_utils, + msg_fields::protocols::notification::ack::AckStatus, msg_types::cred_issuance::CredentialIssuanceTypeV1_0, }; #[test] fn test_minimal_ack_cred() { - let content = AckCredentialContent::new(AckStatus::Ok); + let content: AckCredentialContent = AckContent::builder().status(AckStatus::Ok).build(); - let decorators = AckDecorators::new(make_extended_thread()); + let decorators = AckDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread }); @@ -46,13 +60,15 @@ mod tests { #[test] fn test_extended_ack_cred() { - let content = AckCredentialContent::new(AckStatus::Ok); + let content: AckCredentialContent = AckContent::builder().status(AckStatus::Ok).build(); - let mut decorators = AckDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = AckDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread, "~timing": decorators.timing }); diff --git a/messages/src/msg_fields/protocols/cred_issuance/issue_credential.rs b/messages/src/msg_fields/protocols/cred_issuance/issue_credential.rs index 8f0f9e22f9..409e84a82c 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/issue_credential.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/issue_credential.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{attachment::Attachment, please_ack::PleaseAck, thread::Thread, timing::Timing}, @@ -7,45 +8,29 @@ use crate::{ pub type IssueCredential = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct IssueCredentialContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, #[serde(rename = "credentials~attach")] pub credentials_attach: Vec, } -impl IssueCredentialContent { - pub fn new(credentials_attach: Vec) -> Self { - Self { - comment: None, - credentials_attach, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct IssueCredentialDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~please_ack")] #[serde(skip_serializing_if = "Option::is_none")] pub please_ack: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl IssueCredentialDecorators { - pub fn new(thread: Thread) -> Self { - Self { - thread, - please_ack: None, - timing: None, - } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -64,9 +49,13 @@ mod tests { #[test] fn test_minimal_issue_cred() { - let content = IssueCredentialContent::new(vec![make_extended_attachment()]); + let content = IssueCredentialContent::builder() + .credentials_attach(vec![make_extended_attachment()]) + .build(); - let decorators = IssueCredentialDecorators::new(make_extended_thread()); + let decorators = IssueCredentialDecorators::builder() + .thread(make_extended_thread()) + .build(); let expected = json!({ "credentials~attach": content.credentials_attach, @@ -83,12 +72,16 @@ mod tests { #[test] fn test_extended_issue_cred() { - let mut content = IssueCredentialContent::new(vec![make_extended_attachment()]); - content.comment = Some("test_comment".to_owned()); - - let mut decorators = IssueCredentialDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); - decorators.please_ack = Some(make_minimal_please_ack()); + let content = IssueCredentialContent::builder() + .credentials_attach(vec![make_extended_attachment()]) + .comment("test_comment".to_owned()) + .build(); + + let decorators = IssueCredentialDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .please_ack(make_minimal_please_ack()) + .build(); let expected = json!({ "credentials~attach": content.credentials_attach, diff --git a/messages/src/msg_fields/protocols/cred_issuance/mod.rs b/messages/src/msg_fields/protocols/cred_issuance/mod.rs index ba3abc38df..1e729147a5 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/mod.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/mod.rs @@ -12,6 +12,7 @@ use std::str::FromStr; use derive_more::From; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use shared_vcx::misc::utils::CowStr; +use typed_builder::TypedBuilder; use self::{ ack::{AckCredential, AckCredentialContent}, @@ -110,7 +111,7 @@ impl CredentialPreview { /// Non-standalone message type. /// This is only encountered as part of an existent message. /// It is not a message on it's own. -#[derive(Copy, Clone, Debug, Deserialize, PartialEq)] +#[derive(Copy, Clone, Debug, Default, Deserialize, PartialEq)] #[serde(try_from = "CowStr")] struct CredentialPreviewMsgType; @@ -150,26 +151,17 @@ impl Serialize for CredentialPreviewMsgType { } } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, TypedBuilder)] #[serde(rename_all = "kebab-case")] pub struct CredentialAttr { pub name: String, pub value: String, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "mime-type")] pub mime_type: Option, } -impl CredentialAttr { - pub fn new(name: String, value: String) -> Self { - Self { - name, - value, - mime_type: None, - } - } -} - transit_to_aries_msg!(OfferCredentialContent: OfferCredentialDecorators, CredentialIssuance); transit_to_aries_msg!( ProposeCredentialContent: ProposeCredentialDecorators, diff --git a/messages/src/msg_fields/protocols/cred_issuance/offer_credential.rs b/messages/src/msg_fields/protocols/cred_issuance/offer_credential.rs index ee1469a4e2..b596a0fd25 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/offer_credential.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/offer_credential.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use super::CredentialPreview; use crate::{ @@ -8,8 +9,9 @@ use crate::{ pub type OfferCredential = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct OfferCredentialContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, pub credential_preview: CredentialPreview, @@ -17,21 +19,13 @@ pub struct OfferCredentialContent { pub offers_attach: Vec, } -impl OfferCredentialContent { - pub fn new(credential_preview: CredentialPreview, offers_attach: Vec) -> Self { - Self { - comment: None, - credential_preview, - offers_attach, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct OfferCredentialDecorators { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "~thread")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -56,9 +50,16 @@ mod tests { #[test] fn test_minimal_offer_cred() { - let attribute = CredentialAttr::new("test_attribute_name".to_owned(), "test_attribute_value".to_owned()); + let attribute = CredentialAttr::builder() + .name("test_attribute_name".to_owned()) + .value("test_attribute_value".to_owned()) + .build(); + let preview = CredentialPreview::new(vec![attribute]); - let content = OfferCredentialContent::new(preview, vec![make_extended_attachment()]); + let content = OfferCredentialContent::builder() + .credential_preview(preview) + .offers_attach(vec![make_extended_attachment()]) + .build(); let decorators = OfferCredentialDecorators::default(); @@ -77,14 +78,22 @@ mod tests { #[test] fn test_extended_offer_cred() { - let attribute = CredentialAttr::new("test_attribute_name".to_owned(), "test_attribute_value".to_owned()); + let attribute = CredentialAttr::builder() + .name("test_attribute_name".to_owned()) + .value("test_attribute_value".to_owned()) + .build(); + let preview = CredentialPreview::new(vec![attribute]); - let mut content = OfferCredentialContent::new(preview, vec![make_extended_attachment()]); - content.comment = Some("test_comment".to_owned()); + let content = OfferCredentialContent::builder() + .credential_preview(preview) + .offers_attach(vec![make_extended_attachment()]) + .comment("test_comment".to_owned()) + .build(); - let mut decorators = OfferCredentialDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = OfferCredentialDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "offers~attach": content.offers_attach, diff --git a/messages/src/msg_fields/protocols/cred_issuance/problem_report.rs b/messages/src/msg_fields/protocols/cred_issuance/problem_report.rs index 95d8923370..ae6763b81b 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/problem_report.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/problem_report.rs @@ -1,18 +1,117 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::report_problem::{ProblemReportContent, ProblemReportDecorators}, + msg_fields::protocols::report_problem::{ProblemReport, ProblemReportContent, ProblemReportDecorators}, msg_parts::MsgParts, }; pub type CredIssuanceProblemReport = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct CredIssuanceProblemReportContent(pub ProblemReportContent); +pub struct CredIssuanceProblemReportContent { + pub inner: ProblemReportContent, +} + +impl From for CredIssuanceProblemReportContent { + fn from(value: ProblemReportContent) -> Self { + Self { inner: value } + } +} + +impl From for ProblemReport { + fn from(value: CredIssuanceProblemReport) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use std::collections::HashMap; + + use serde_json::json; + + use super::*; + use crate::{ + decorators::{ + localization::tests::make_extended_field_localization, thread::tests::make_extended_thread, + timing::tests::make_extended_timing, + }, + misc::test_utils, + msg_fields::protocols::report_problem::{Description, Impact, Where, WhereParty, WhoRetries}, + msg_types::cred_issuance::CredentialIssuanceTypeV1_0, + }; + + #[test] + fn test_minimal_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + + let content: CredIssuanceProblemReportContent = + ProblemReportContent::builder().description(description).build(); + let decorators = ProblemReportDecorators::default(); + + let expected = json!({ + "description": content.inner.description + }); + + test_utils::test_msg(content, decorators, CredentialIssuanceTypeV1_0::ProblemReport, expected); + } + + #[test] + fn test_extended_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + + let content: ProblemReportContent = ProblemReportContent::builder() + .description(description) + .who_retries(WhoRetries::Me) + .fix_hint("test_fix_hint".to_owned()) + .impact(Impact::Connection) + .location(Where::new(WhereParty::Me, "test_location".to_owned())) + .noticed_time("test_noticed_time".to_owned()) + .tracking_uri("https://dummy.dummy/dummy".parse().unwrap()) + .escalation_uri("https://dummy.dummy/dummy".parse().unwrap()) + .problem_items(vec![HashMap::from([( + "test_prob_item_key".to_owned(), + "test_prob_item_value".to_owned(), + )])]) + .build(); + + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .description_locale(make_extended_field_localization()) + .fix_hint_locale(make_extended_field_localization()) + .build(); + + let expected = json!({ + "description": content.description, + "who_retries": content.who_retries, + "fix-hint": content.fix_hint, + "impact": content.impact, + "where": content.location, + "noticed_time": content.noticed_time, + "tracking-uri": content.tracking_uri, + "escalation-uri": content.escalation_uri, + "problem_items": content.problem_items, + "~thread": decorators.thread, + "~timing": decorators.timing, + "description~l10n": decorators.description_locale, + "fix-hint~l10n": decorators.fix_hint_locale + }); + + let content = CredIssuanceProblemReportContent::builder().inner(content).build(); -impl CredIssuanceProblemReportContent { - pub fn new(code: String) -> Self { - Self(ProblemReportContent::new(code)) + test_utils::test_msg(content, decorators, CredentialIssuanceTypeV1_0::ProblemReport, expected); } } diff --git a/messages/src/msg_fields/protocols/cred_issuance/propose_credential.rs b/messages/src/msg_fields/protocols/cred_issuance/propose_credential.rs index aa4dfacee0..40a4d1fe68 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/propose_credential.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/propose_credential.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use super::CredentialPreview; use crate::{ @@ -8,8 +9,9 @@ use crate::{ pub type ProposeCredential = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ProposeCredentialContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, pub credential_proposal: CredentialPreview, @@ -17,22 +19,13 @@ pub struct ProposeCredentialContent { pub cred_def_id: String, } -impl ProposeCredentialContent { - pub fn new(credential_proposal: CredentialPreview, schema_id: String, cred_def_id: String) -> Self { - Self { - comment: None, - credential_proposal, - schema_id, - cred_def_id, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct ProposeCredentialDecorators { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "~thread")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -54,10 +47,16 @@ mod tests { #[test] fn test_minimal_propose_cred() { - let attribute = CredentialAttr::new("test_attribute_name".to_owned(), "test_attribute_value".to_owned()); + let attribute = CredentialAttr::builder() + .name("test_attribute_name".to_owned()) + .value("test_attribute_value".to_owned()) + .build(); let preview = CredentialPreview::new(vec![attribute]); - let content = - ProposeCredentialContent::new(preview, "test_schema_id".to_owned(), "test_cred_def_id".to_owned()); + let content = ProposeCredentialContent::builder() + .credential_proposal(preview) + .schema_id("test_schema_id".to_owned()) + .cred_def_id("test_cred_def_id".to_owned()) + .build(); let decorators = ProposeCredentialDecorators::default(); @@ -77,16 +76,22 @@ mod tests { #[test] fn test_extended_propose_cred() { - let attribute = CredentialAttr::new("test_attribute_name".to_owned(), "test_attribute_value".to_owned()); + let attribute = CredentialAttr::builder() + .name("test_attribute_name".to_owned()) + .value("test_attribute_value".to_owned()) + .build(); let preview = CredentialPreview::new(vec![attribute]); - let mut content = - ProposeCredentialContent::new(preview, "test_schema_id".to_owned(), "test_cred_def_id".to_owned()); - - content.comment = Some("test_comment".to_owned()); - - let mut decorators = ProposeCredentialDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let content = ProposeCredentialContent::builder() + .credential_proposal(preview) + .schema_id("test_schema_id".to_owned()) + .cred_def_id("test_cred_def_id".to_owned()) + .comment("test_comment".to_owned()) + .build(); + + let decorators = ProposeCredentialDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "credential_proposal": content.credential_proposal, diff --git a/messages/src/msg_fields/protocols/cred_issuance/request_credential.rs b/messages/src/msg_fields/protocols/cred_issuance/request_credential.rs index 6c2ee90bdb..bc656db6c9 100644 --- a/messages/src/msg_fields/protocols/cred_issuance/request_credential.rs +++ b/messages/src/msg_fields/protocols/cred_issuance/request_credential.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{attachment::Attachment, thread::Thread, timing::Timing}, @@ -7,28 +8,22 @@ use crate::{ pub type RequestCredential = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct RequestCredentialContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, #[serde(rename = "requests~attach")] pub requests_attach: Vec, } -impl RequestCredentialContent { - pub fn new(requests_attach: Vec) -> Self { - Self { - comment: None, - requests_attach, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct RequestCredentialDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -49,7 +44,9 @@ mod tests { #[test] fn test_minimal_request_cred() { - let content = RequestCredentialContent::new(vec![make_extended_attachment()]); + let content = RequestCredentialContent::builder() + .requests_attach(vec![make_extended_attachment()]) + .build(); let decorators = RequestCredentialDecorators::default(); @@ -67,11 +64,14 @@ mod tests { #[test] fn test_extended_request_cred() { - let mut content = RequestCredentialContent::new(vec![make_extended_attachment()]); - content.comment = Some("test_comment".to_owned()); + let content = RequestCredentialContent::builder() + .requests_attach(vec![make_extended_attachment()]) + .comment("test_comment".to_owned()) + .build(); - let mut decorators = RequestCredentialDecorators::default(); - decorators.thread = Some(make_extended_thread()); + let decorators = RequestCredentialDecorators::builder() + .thread(make_extended_thread()) + .build(); let expected = json!({ "requests~attach": content.requests_attach, diff --git a/messages/src/msg_fields/protocols/discover_features/disclose.rs b/messages/src/msg_fields/protocols/discover_features/disclose.rs index 50588c062f..95c43807a8 100644 --- a/messages/src/msg_fields/protocols/discover_features/disclose.rs +++ b/messages/src/msg_fields/protocols/discover_features/disclose.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; use super::ProtocolDescriptor; use crate::{ @@ -10,7 +11,7 @@ use crate::{ pub type Disclose = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct DiscloseContent { pub protocols: Vec, } @@ -21,9 +22,10 @@ impl Default for DiscloseContent { for entries in PROTOCOL_REGISTRY.clone().into_values() { for entry in entries { - let pid = MaybeKnown::Known(entry.protocol); - let mut pd = ProtocolDescriptor::new(pid); - pd.roles = Some(entry.roles); + let pd = ProtocolDescriptor::builder() + .pid(MaybeKnown::Known(entry.protocol)) + .roles(entry.roles) + .build(); protocols.push(pd); } } @@ -32,21 +34,16 @@ impl Default for DiscloseContent { } } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct DiscloseDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl DiscloseDecorators { - pub fn new(thread: Thread) -> Self { - Self { thread, timing: None } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -65,7 +62,7 @@ mod tests { fn test_minimal_disclose() { let content = DiscloseContent::default(); - let decorators = DiscloseDecorators::new(make_extended_thread()); + let decorators = DiscloseDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "protocols": content.protocols, @@ -82,11 +79,15 @@ mod tests { content.protocols.pop(); content.protocols.pop(); - let dummy_protocol_descriptor = ProtocolDescriptor::new(MaybeKnown::Unknown("test_dummy_pid".to_owned())); + let dummy_protocol_descriptor = ProtocolDescriptor::builder() + .pid(MaybeKnown::Unknown("test_dummy_pid".to_owned())) + .build(); content.protocols.push(dummy_protocol_descriptor); - let mut decorators = DiscloseDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = DiscloseDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "protocols": content.protocols, diff --git a/messages/src/msg_fields/protocols/discover_features/mod.rs b/messages/src/msg_fields/protocols/discover_features/mod.rs index 3f0d2954bb..6a28ae74f7 100644 --- a/messages/src/msg_fields/protocols/discover_features/mod.rs +++ b/messages/src/msg_fields/protocols/discover_features/mod.rs @@ -6,6 +6,7 @@ pub mod query; use derive_more::From; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; use self::{ disclose::{Disclose, DiscloseContent, DiscloseDecorators}, @@ -58,19 +59,14 @@ impl DelayedSerde for DiscoverFeatures { } } -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ProtocolDescriptor { pub pid: MaybeKnown, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub roles: Option>>, } -impl ProtocolDescriptor { - pub fn new(pid: MaybeKnown) -> Self { - Self { pid, roles: None } - } -} - transit_to_aries_msg!(QueryContent: QueryDecorators, DiscoverFeatures); transit_to_aries_msg!(DiscloseContent: DiscloseDecorators, DiscoverFeatures); diff --git a/messages/src/msg_fields/protocols/discover_features/query.rs b/messages/src/msg_fields/protocols/discover_features/query.rs index 9bfcd50f87..3cf7a7a371 100644 --- a/messages/src/msg_fields/protocols/discover_features/query.rs +++ b/messages/src/msg_fields/protocols/discover_features/query.rs @@ -1,23 +1,21 @@ use serde::{Deserialize, Serialize}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; use super::ProtocolDescriptor; use crate::{decorators::timing::Timing, msg_parts::MsgParts, msg_types::registry::PROTOCOL_REGISTRY}; pub type Query = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct QueryContent { pub query: String, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, } impl QueryContent { - pub fn new(query: String) -> Self { - Self { query, comment: None } - } - /// Looks up into the [`PROTOCOL_REGISTRY`] and returns a [`Vec Vec { let mut protocols = Vec::new(); @@ -30,9 +28,10 @@ impl QueryContent { for entries in PROTOCOL_REGISTRY.values() { for entry in entries { if entry.str_pid.starts_with(query) { - let pid = MaybeKnown::Known(entry.protocol); - let mut pd = ProtocolDescriptor::new(pid); - pd.roles = Some(entry.roles.clone()); + let pd = ProtocolDescriptor::builder() + .pid(MaybeKnown::Known(entry.protocol)) + .roles(entry.roles.clone()) + .build(); protocols.push(pd); } } @@ -42,8 +41,9 @@ impl QueryContent { } } -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct QueryDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -67,7 +67,7 @@ mod tests { #[test] fn test_minimal_query() { - let content = QueryContent::new("*".to_owned()); + let content = QueryContent::builder().query("*".to_owned()).build(); let decorators = QueryDecorators::default(); @@ -80,11 +80,12 @@ mod tests { #[test] fn test_extended_query() { - let mut content = QueryContent::new("*".to_owned()); - content.comment = Some("test_comment".to_owned()); + let content = QueryContent::builder() + .query("*".to_owned()) + .comment("test_comment".to_owned()) + .build(); - let mut decorators = QueryDecorators::default(); - decorators.timing = Some(make_extended_timing()); + let decorators = QueryDecorators::builder().timing(make_extended_timing()).build(); let expected = json!({ "query": content.query, @@ -97,15 +98,17 @@ mod tests { #[test] fn test_lookup_match_all() { - let matched_all = QueryContent::new("*".to_owned()).lookup(); + let matched_all = QueryContent::builder().query("*".to_owned()).build().lookup(); let mut protocols = Vec::new(); for entries in PROTOCOL_REGISTRY.values() { for entry in entries { let pid = MaybeKnown::Known(entry.protocol); - let mut pd = ProtocolDescriptor::new(pid); - pd.roles = Some(entry.roles.clone()); + let pd = ProtocolDescriptor::builder() + .pid(pid) + .roles(entry.roles.clone()) + .build(); protocols.push(pd); } } @@ -115,12 +118,17 @@ mod tests { #[test] fn test_lookup_match_protocol() { - let matched_protocol = QueryContent::new("https://didcomm.org/connections/*".to_owned()).lookup(); + let matched_protocol = QueryContent::builder() + .query("https://didcomm.org/connections/*".to_owned()) + .build() + .lookup(); let pid = ConnectionTypeV1::new_v1_0(); let roles = pid.roles(); - let mut pd = ProtocolDescriptor::new(MaybeKnown::Known(pid.into())); - pd.roles = Some(roles); + let pd = ProtocolDescriptor::builder() + .pid(MaybeKnown::Known(pid.into())) + .roles(roles) + .build(); let protocols = vec![pd]; @@ -129,12 +137,16 @@ mod tests { #[test] fn test_lookup_match_version() { - let matched_protocol = QueryContent::new("https://didcomm.org/connections/1.*".to_owned()).lookup(); + let matched_protocol = QueryContent::builder() + .query("https://didcomm.org/connections/1.*".to_owned()) + .build() + .lookup(); let pid = ConnectionTypeV1::new_v1_0(); - let roles = pid.roles(); - let mut pd = ProtocolDescriptor::new(MaybeKnown::Known(pid.into())); - pd.roles = Some(roles); + let pd = ProtocolDescriptor::builder() + .pid(MaybeKnown::Known(pid.into())) + .roles(pid.roles()) + .build(); let protocols = vec![pd]; @@ -143,7 +155,10 @@ mod tests { #[test] fn test_lookup_match_none() { - let matched_protocol = QueryContent::new("https://didcomm.org/non-existent/*".to_owned()).lookup(); + let matched_protocol = QueryContent::builder() + .query("https://didcomm.org/non-existent/*".to_owned()) + .build() + .lookup(); let protocols = Vec::::new(); assert_eq!(protocols, matched_protocol); diff --git a/messages/src/msg_fields/protocols/notification/ack.rs b/messages/src/msg_fields/protocols/notification/ack.rs index 58e31a262c..2a1651b16c 100644 --- a/messages/src/msg_fields/protocols/notification/ack.rs +++ b/messages/src/msg_fields/protocols/notification/ack.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -7,17 +8,12 @@ use crate::{ pub type Ack = MsgParts; -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TypedBuilder)] +#[builder(build_method(into))] pub struct AckContent { pub status: AckStatus, } -impl AckContent { - pub fn new(status: AckStatus) -> Self { - Self { status } - } -} - #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "UPPERCASE")] pub enum AckStatus { @@ -25,21 +21,16 @@ pub enum AckStatus { Pending, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TypedBuilder)] pub struct AckDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl AckDecorators { - pub fn new(thread: Thread) -> Self { - Self { thread, timing: None } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -55,9 +46,9 @@ mod tests { #[test] fn test_minimal_ack() { - let content = AckContent::new(AckStatus::Ok); + let content: AckContent = AckContent::builder().status(AckStatus::Ok).build(); - let decorators = AckDecorators::new(make_extended_thread()); + let decorators = AckDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "status": content.status, @@ -69,10 +60,12 @@ mod tests { #[test] fn test_extended_ack() { - let content = AckContent::new(AckStatus::Ok); + let content: AckContent = AckContent::builder().status(AckStatus::Ok).build(); - let mut decorators = AckDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = AckDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "status": content.status, diff --git a/messages/src/msg_fields/protocols/notification/problem_report.rs b/messages/src/msg_fields/protocols/notification/problem_report.rs index 2b9f7fd061..2b3bfa899b 100644 --- a/messages/src/msg_fields/protocols/notification/problem_report.rs +++ b/messages/src/msg_fields/protocols/notification/problem_report.rs @@ -1,18 +1,115 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::report_problem::{ProblemReportContent, ProblemReportDecorators}, + msg_fields::protocols::report_problem::{ProblemReport, ProblemReportContent, ProblemReportDecorators}, msg_parts::MsgParts, }; pub type NotificationProblemReport = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct NotificationProblemReportContent(pub ProblemReportContent); +pub struct NotificationProblemReportContent { + pub inner: ProblemReportContent, +} + +impl From for NotificationProblemReportContent { + fn from(value: ProblemReportContent) -> Self { + Self { inner: value } + } +} + +impl From for ProblemReport { + fn from(value: NotificationProblemReport) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use std::collections::HashMap; + + use serde_json::json; + + use super::*; + use crate::{ + decorators::{ + localization::tests::make_extended_field_localization, thread::tests::make_extended_thread, + timing::tests::make_extended_timing, + }, + misc::test_utils, + msg_fields::protocols::report_problem::{Description, Impact, Where, WhereParty, WhoRetries}, + msg_types::notification::NotificationTypeV1_0, + }; + + #[test] + fn test_minimal_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: NotificationProblemReportContent = + ProblemReportContent::builder().description(description).build(); + let decorators = ProblemReportDecorators::default(); + + let expected = json!({ + "description": content.inner.description + }); + + test_utils::test_msg(content, decorators, NotificationTypeV1_0::ProblemReport, expected); + } + + #[test] + fn test_extended_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: ProblemReportContent = ProblemReportContent::builder() + .description(description) + .who_retries(WhoRetries::Me) + .fix_hint("test_fix_hint".to_owned()) + .impact(Impact::Connection) + .location(Where::new(WhereParty::Me, "test_location".to_owned())) + .noticed_time("test_noticed_time".to_owned()) + .tracking_uri("https://dummy.dummy/dummy".parse().unwrap()) + .escalation_uri("https://dummy.dummy/dummy".parse().unwrap()) + .problem_items(vec![HashMap::from([( + "test_prob_item_key".to_owned(), + "test_prob_item_value".to_owned(), + )])]) + .build(); + + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .description_locale(make_extended_field_localization()) + .fix_hint_locale(make_extended_field_localization()) + .build(); + + let expected = json!({ + "description": content.description, + "who_retries": content.who_retries, + "fix-hint": content.fix_hint, + "impact": content.impact, + "where": content.location, + "noticed_time": content.noticed_time, + "tracking-uri": content.tracking_uri, + "escalation-uri": content.escalation_uri, + "problem_items": content.problem_items, + "~thread": decorators.thread, + "~timing": decorators.timing, + "description~l10n": decorators.description_locale, + "fix-hint~l10n": decorators.fix_hint_locale + }); + + let content = NotificationProblemReportContent::builder().inner(content).build(); -impl NotificationProblemReportContent { - pub fn new(code: String) -> Self { - Self(ProblemReportContent::new(code)) + test_utils::test_msg(content, decorators, NotificationTypeV1_0::ProblemReport, expected); } } diff --git a/messages/src/msg_fields/protocols/out_of_band/invitation.rs b/messages/src/msg_fields/protocols/out_of_band/invitation.rs index d4c756a005..06c8550802 100644 --- a/messages/src/msg_fields/protocols/out_of_band/invitation.rs +++ b/messages/src/msg_fields/protocols/out_of_band/invitation.rs @@ -2,6 +2,7 @@ use diddoc_legacy::aries::service::AriesService; use serde::{Deserialize, Serialize}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; use super::OobGoalCode; use crate::{ @@ -13,40 +14,33 @@ use crate::{ pub type Invitation = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct InvitationContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub label: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub goal_code: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub goal: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub accept: Option>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub handshake_protocols: Option>>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "requests~attach")] pub requests_attach: Option>, pub services: Vec, } -impl InvitationContent { - pub fn new(services: Vec) -> Self { - Self { - label: None, - goal_code: None, - goal: None, - accept: None, - handshake_protocols: None, - requests_attach: None, - services, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct InvitationDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -74,7 +68,9 @@ mod tests { #[test] fn test_minimal_oob_invitation() { - let content = InvitationContent::new(vec![OobService::Did("test_service_did".to_owned())]); + let content = InvitationContent::builder() + .services(vec![OobService::Did("test_service_did".to_owned())]) + .build(); let decorators = InvitationDecorators::default(); @@ -87,17 +83,17 @@ mod tests { #[test] fn test_extended_oob_invitation() { - let mut content = InvitationContent::new(vec![OobService::Did("test_service_did".to_owned())]); - - content.requests_attach = Some(vec![make_extended_attachment()]); - content.label = Some("test_label".to_owned()); - content.goal_code = Some(MaybeKnown::Known(OobGoalCode::P2PMessaging)); - content.goal = Some("test_oob_goal".to_owned()); - content.accept = Some(vec![MimeType::Json, MimeType::Plain]); - content.handshake_protocols = Some(vec![MaybeKnown::Known(ConnectionTypeV1::new_v1_0().into())]); - - let mut decorators = InvitationDecorators::default(); - decorators.timing = Some(make_extended_timing()); + let content = InvitationContent::builder() + .services(vec![OobService::Did("test_service_did".to_owned())]) + .requests_attach(vec![make_extended_attachment()]) + .label("test_label".to_owned()) + .goal_code(MaybeKnown::Known(OobGoalCode::P2PMessaging)) + .goal("test_oob_goal".to_owned()) + .accept(vec![MimeType::Json, MimeType::Plain]) + .handshake_protocols(vec![MaybeKnown::Known(ConnectionTypeV1::new_v1_0().into())]) + .build(); + + let decorators = InvitationDecorators::builder().timing(make_extended_timing()).build(); let expected = json!({ "label": content.label, diff --git a/messages/src/msg_fields/protocols/out_of_band/reuse.rs b/messages/src/msg_fields/protocols/out_of_band/reuse.rs index 14bfc5ffba..ca5e052b63 100644 --- a/messages/src/msg_fields/protocols/out_of_band/reuse.rs +++ b/messages/src/msg_fields/protocols/out_of_band/reuse.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; -// Bind `shared_vcx::misc::serde_ignored::SerdeIgnored` type as `NoDecorators`. -use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; +use shared_vcx::misc::serde_ignored::SerdeIgnored; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -10,25 +10,23 @@ use crate::{ pub type HandshakeReuse = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct HandshakeReuseContent(NoDecorators); +pub struct HandshakeReuseContent { + #[builder(default, setter(skip))] + inner: SerdeIgnored, +} -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct HandshakeReuseDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl HandshakeReuseDecorators { - pub fn new(thread: Thread) -> Self { - Self { thread, timing: None } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -46,7 +44,9 @@ mod tests { fn test_minimal_reuse() { let content = HandshakeReuseContent::default(); - let decorators = HandshakeReuseDecorators::new(make_extended_thread()); + let decorators = HandshakeReuseDecorators::builder() + .thread(make_extended_thread()) + .build(); let expected = json!({ "~thread": decorators.thread @@ -59,8 +59,10 @@ mod tests { fn test_extended_reuse() { let content = HandshakeReuseContent::default(); - let mut decorators = HandshakeReuseDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = HandshakeReuseDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "~thread": decorators.thread, diff --git a/messages/src/msg_fields/protocols/out_of_band/reuse_accepted.rs b/messages/src/msg_fields/protocols/out_of_band/reuse_accepted.rs index e3ad772ca7..febe2e5fec 100644 --- a/messages/src/msg_fields/protocols/out_of_band/reuse_accepted.rs +++ b/messages/src/msg_fields/protocols/out_of_band/reuse_accepted.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; -// Bind `shared_vcx::misc::serde_ignored::SerdeIgnored` type as `NoDecorators`. -use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; +use shared_vcx::misc::serde_ignored::SerdeIgnored; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -10,25 +10,23 @@ use crate::{ pub type HandshakeReuseAccepted = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct HandshakeReuseAcceptedContent(NoDecorators); +pub struct HandshakeReuseAcceptedContent { + #[builder(default, setter(skip))] + inner: SerdeIgnored, +} -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct HandshakeReuseAcceptedDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl HandshakeReuseAcceptedDecorators { - pub fn new(thread: Thread) -> Self { - Self { thread, timing: None } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -46,7 +44,9 @@ mod tests { fn test_minimal_reuse_accepted() { let content = HandshakeReuseAcceptedContent::default(); - let decorators = HandshakeReuseAcceptedDecorators::new(make_extended_thread()); + let decorators = HandshakeReuseAcceptedDecorators::builder() + .thread(make_extended_thread()) + .build(); let expected = json!({ "~thread": decorators.thread @@ -59,8 +59,10 @@ mod tests { fn test_extended_reuse_accepted() { let content = HandshakeReuseAcceptedContent::default(); - let mut decorators = HandshakeReuseAcceptedDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = HandshakeReuseAcceptedDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "~thread": decorators.thread, diff --git a/messages/src/msg_fields/protocols/present_proof/ack.rs b/messages/src/msg_fields/protocols/present_proof/ack.rs index fff520c5f5..045dfb707e 100644 --- a/messages/src/msg_fields/protocols/present_proof/ack.rs +++ b/messages/src/msg_fields/protocols/present_proof/ack.rs @@ -1,19 +1,32 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}, + msg_fields::protocols::notification::ack::{Ack, AckContent, AckDecorators}, msg_parts::MsgParts, }; pub type AckPresentation = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct AckPresentationContent(pub AckContent); +pub struct AckPresentationContent { + pub inner: AckContent, +} + +impl From for AckPresentationContent { + fn from(value: AckContent) -> Self { + Self { inner: value } + } +} -impl AckPresentationContent { - pub fn new(status: AckStatus) -> Self { - Self(AckContent::new(status)) +impl From for Ack { + fn from(value: AckPresentation) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() } } @@ -27,17 +40,18 @@ mod tests { use crate::{ decorators::{thread::tests::make_extended_thread, timing::tests::make_extended_timing}, misc::test_utils, + msg_fields::protocols::notification::ack::AckStatus, msg_types::present_proof::PresentProofTypeV1_0, }; #[test] fn test_minimal_ack_proof() { - let content = AckPresentationContent::new(AckStatus::Ok); + let content: AckPresentationContent = AckContent::builder().status(AckStatus::Ok).build(); - let decorators = AckDecorators::new(make_extended_thread()); + let decorators = AckDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread }); @@ -46,13 +60,15 @@ mod tests { #[test] fn test_extended_ack_proof() { - let content = AckPresentationContent::new(AckStatus::Ok); + let content: AckPresentationContent = AckContent::builder().status(AckStatus::Ok).build(); - let mut decorators = AckDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = AckDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread, "~timing": decorators.timing }); diff --git a/messages/src/msg_fields/protocols/present_proof/present.rs b/messages/src/msg_fields/protocols/present_proof/present.rs index 179c50b971..9bcd63f414 100644 --- a/messages/src/msg_fields/protocols/present_proof/present.rs +++ b/messages/src/msg_fields/protocols/present_proof/present.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{attachment::Attachment, please_ack::PleaseAck, thread::Thread, timing::Timing}, @@ -7,45 +8,29 @@ use crate::{ pub type Presentation = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct PresentationContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, #[serde(rename = "presentations~attach")] pub presentations_attach: Vec, } -impl PresentationContent { - pub fn new(presentations_attach: Vec) -> Self { - Self { - comment: None, - presentations_attach, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct PresentationDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~please_ack")] #[serde(skip_serializing_if = "Option::is_none")] pub please_ack: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl PresentationDecorators { - pub fn new(thread: Thread) -> Self { - Self { - thread, - please_ack: None, - timing: None, - } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -64,9 +49,11 @@ mod tests { #[test] fn test_minimal_present_proof() { - let content = PresentationContent::new(vec![make_extended_attachment()]); + let content = PresentationContent::builder() + .presentations_attach(vec![make_extended_attachment()]) + .build(); - let decorators = PresentationDecorators::new(make_extended_thread()); + let decorators = PresentationDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "presentations~attach": content.presentations_attach, @@ -78,12 +65,16 @@ mod tests { #[test] fn test_extended_present_proof() { - let mut content = PresentationContent::new(vec![make_extended_attachment()]); - content.comment = Some("test_comment".to_owned()); - - let mut decorators = PresentationDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); - decorators.please_ack = Some(make_minimal_please_ack()); + let content = PresentationContent::builder() + .presentations_attach(vec![make_extended_attachment()]) + .comment("test_comment".to_owned()) + .build(); + + let decorators = PresentationDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .please_ack(make_minimal_please_ack()) + .build(); let expected = json!({ "comment": content.comment, diff --git a/messages/src/msg_fields/protocols/present_proof/problem_report.rs b/messages/src/msg_fields/protocols/present_proof/problem_report.rs index 3971451ceb..10cb5a0c01 100644 --- a/messages/src/msg_fields/protocols/present_proof/problem_report.rs +++ b/messages/src/msg_fields/protocols/present_proof/problem_report.rs @@ -1,18 +1,116 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::report_problem::{ProblemReportContent, ProblemReportDecorators}, + msg_fields::protocols::report_problem::{ProblemReport, ProblemReportContent, ProblemReportDecorators}, msg_parts::MsgParts, }; pub type PresentProofProblemReport = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct PresentProofProblemReportContent(pub ProblemReportContent); +pub struct PresentProofProblemReportContent { + pub inner: ProblemReportContent, +} + +impl From for PresentProofProblemReportContent { + fn from(value: ProblemReportContent) -> Self { + Self { inner: value } + } +} + +impl From for ProblemReport { + fn from(value: PresentProofProblemReport) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use std::collections::HashMap; + + use serde_json::json; + + use super::*; + use crate::{ + decorators::{ + localization::tests::make_extended_field_localization, thread::tests::make_extended_thread, + timing::tests::make_extended_timing, + }, + misc::test_utils, + msg_fields::protocols::report_problem::{Description, Impact, Where, WhereParty, WhoRetries}, + msg_types::present_proof::PresentProofTypeV1_0, + }; + + #[test] + fn test_minimal_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: ProblemReportContent = ProblemReportContent::builder().description(description).build(); + let decorators = ProblemReportDecorators::default(); + + let expected = json!({ + "description": content.description + }); + + let content = PresentProofProblemReportContent::builder().inner(content).build(); + + test_utils::test_msg(content, decorators, PresentProofTypeV1_0::ProblemReport, expected); + } + + #[test] + fn test_extended_problem_report() { + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: ProblemReportContent = ProblemReportContent::builder() + .description(description) + .who_retries(WhoRetries::Me) + .fix_hint("test_fix_hint".to_owned()) + .impact(Impact::Connection) + .location(Where::new(WhereParty::Me, "test_location".to_owned())) + .noticed_time("test_noticed_time".to_owned()) + .tracking_uri("https://dummy.dummy/dummy".parse().unwrap()) + .escalation_uri("https://dummy.dummy/dummy".parse().unwrap()) + .problem_items(vec![HashMap::from([( + "test_prob_item_key".to_owned(), + "test_prob_item_value".to_owned(), + )])]) + .build(); + + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .description_locale(make_extended_field_localization()) + .fix_hint_locale(make_extended_field_localization()) + .build(); + + let expected = json!({ + "description": content.description, + "who_retries": content.who_retries, + "fix-hint": content.fix_hint, + "impact": content.impact, + "where": content.location, + "noticed_time": content.noticed_time, + "tracking-uri": content.tracking_uri, + "escalation-uri": content.escalation_uri, + "problem_items": content.problem_items, + "~thread": decorators.thread, + "~timing": decorators.timing, + "description~l10n": decorators.description_locale, + "fix-hint~l10n": decorators.fix_hint_locale + }); + + let content = PresentProofProblemReportContent::builder().inner(content).build(); -impl PresentProofProblemReportContent { - pub fn new(code: String) -> Self { - Self(ProblemReportContent::new(code)) + test_utils::test_msg(content, decorators, PresentProofTypeV1_0::ProblemReport, expected); } } diff --git a/messages/src/msg_fields/protocols/present_proof/propose.rs b/messages/src/msg_fields/protocols/present_proof/propose.rs index 5fd45366bb..483dd0de91 100644 --- a/messages/src/msg_fields/protocols/present_proof/propose.rs +++ b/messages/src/msg_fields/protocols/present_proof/propose.rs @@ -2,6 +2,7 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; use shared_vcx::misc::utils::CowStr; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -16,27 +17,21 @@ use crate::{ pub type ProposePresentation = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ProposePresentationContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, pub presentation_proposal: PresentationPreview, } -impl ProposePresentationContent { - pub fn new(presentation_proposal: PresentationPreview) -> Self { - Self { - comment: None, - presentation_proposal, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct ProposePresentationDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -63,7 +58,7 @@ impl PresentationPreview { /// Non-standalone message type. /// This is only encountered as part of an existent message. /// It is not a message on it's own. -#[derive(Copy, Clone, Debug, Deserialize, PartialEq)] +#[derive(Copy, Clone, Debug, Default, Deserialize, PartialEq)] #[serde(try_from = "CowStr")] struct PresentationPreviewMsgType; @@ -99,52 +94,34 @@ impl Serialize for PresentationPreviewMsgType { } } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, TypedBuilder)] pub struct PresentationAttr { pub name: String, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub cred_def_id: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "mime-type")] pub mime_type: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub value: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub referent: Option, } -impl PresentationAttr { - pub fn new(name: String) -> Self { - Self { - name, - cred_def_id: None, - mime_type: None, - value: None, - referent: None, - } - } -} - -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, TypedBuilder)] pub struct Predicate { pub name: String, pub predicate: PredicateOperator, pub threshold: i64, + #[builder(default, setter(strip_option))] #[serde(flatten)] pub referent: Option, } -impl Predicate { - pub fn new(name: String, predicate: PredicateOperator, threshold: i64) -> Self { - Self { - name, - predicate, - threshold, - referent: None, - } - } -} - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct Referent { pub cred_def_id: String, @@ -183,14 +160,18 @@ mod tests { #[test] fn test_minimal_propose_proof() { - let attribute = PresentationAttr::new("test_attribute_name".to_owned()); - let predicate = Predicate::new( - "test_predicate_name".to_owned(), - PredicateOperator::GreaterOrEqual, - 1000, - ); + let attribute = PresentationAttr::builder() + .name("test_attribute_name".to_owned()) + .build(); + let predicate = Predicate::builder() + .name("test_predicate_name".to_owned()) + .predicate(PredicateOperator::GreaterOrEqual) + .threshold(1000) + .build(); let preview = PresentationPreview::new(vec![attribute], vec![predicate]); - let content = ProposePresentationContent::new(preview); + let content = ProposePresentationContent::builder() + .presentation_proposal(preview) + .build(); let decorators = ProposePresentationDecorators::default(); @@ -203,19 +184,24 @@ mod tests { #[test] fn test_extended_propose_proof() { - let attribute = PresentationAttr::new("test_attribute_name".to_owned()); - let predicate = Predicate::new( - "test_predicate_name".to_owned(), - PredicateOperator::GreaterOrEqual, - 1000, - ); + let attribute = PresentationAttr::builder() + .name("test_attribute_name".to_owned()) + .build(); + let predicate = Predicate::builder() + .name("test_predicate_name".to_owned()) + .predicate(PredicateOperator::GreaterOrEqual) + .threshold(1000) + .build(); let preview = PresentationPreview::new(vec![attribute], vec![predicate]); - let mut content = ProposePresentationContent::new(preview); - content.comment = Some("test_comment".to_owned()); - - let mut decorators = ProposePresentationDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let content = ProposePresentationContent::builder() + .presentation_proposal(preview) + .comment("test_comment".to_owned()) + .build(); + + let decorators = ProposePresentationDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "comment": content.comment, diff --git a/messages/src/msg_fields/protocols/present_proof/request.rs b/messages/src/msg_fields/protocols/present_proof/request.rs index ce8d3e6d76..4a77fb6de0 100644 --- a/messages/src/msg_fields/protocols/present_proof/request.rs +++ b/messages/src/msg_fields/protocols/present_proof/request.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{attachment::Attachment, thread::Thread, timing::Timing}, @@ -7,28 +8,22 @@ use crate::{ pub type RequestPresentation = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct RequestPresentationContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, #[serde(rename = "request_presentations~attach")] pub request_presentations_attach: Vec, } -impl RequestPresentationContent { - pub fn new(request_presentations_attach: Vec) -> Self { - Self { - comment: None, - request_presentations_attach, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct RequestPresentationDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -52,7 +47,9 @@ mod tests { #[test] fn test_minimal_request_proof() { - let content = RequestPresentationContent::new(vec![make_extended_attachment()]); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![make_extended_attachment()]) + .build(); let decorators = RequestPresentationDecorators::default(); @@ -65,12 +62,15 @@ mod tests { #[test] fn test_extended_request_proof() { - let mut content = RequestPresentationContent::new(vec![make_extended_attachment()]); - content.comment = Some("test_comment".to_owned()); + let content = RequestPresentationContent::builder() + .request_presentations_attach(vec![make_extended_attachment()]) + .comment("test_comment".to_owned()) + .build(); - let mut decorators = RequestPresentationDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = RequestPresentationDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "request_presentations~attach": content.request_presentations_attach, diff --git a/messages/src/msg_fields/protocols/report_problem.rs b/messages/src/msg_fields/protocols/report_problem.rs index 41095c4567..7715d23253 100644 --- a/messages/src/msg_fields/protocols/report_problem.rs +++ b/messages/src/msg_fields/protocols/report_problem.rs @@ -7,6 +7,7 @@ use serde::{ }; use shared_vcx::misc::utils::CowStr; use strum_macros::{AsRefStr, EnumString}; +use typed_builder::TypedBuilder; use url::Url; use crate::{ @@ -22,80 +23,68 @@ use crate::{ pub type ProblemReport = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] +#[builder(build_method(into))] pub struct ProblemReportContent { pub description: Description, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub problem_items: Option>>, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub who_retries: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "fix-hint")] #[serde(skip_serializing_if = "Option::is_none")] pub fix_hint: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub impact: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "where")] #[serde(skip_serializing_if = "Option::is_none")] pub location: Option, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub noticed_time: Option, #[serde(rename = "tracking-uri")] #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] pub tracking_uri: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "escalation-uri")] #[serde(skip_serializing_if = "Option::is_none")] pub escalation_uri: Option, } -impl ProblemReportContent { - pub fn new(code: String) -> Self { - Self { - description: Description::new(code), - problem_items: None, - who_retries: None, - fix_hint: None, - impact: None, - location: None, - noticed_time: None, - tracking_uri: None, - escalation_uri: None, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, TypedBuilder)] pub struct ProblemReportDecorators { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "~thread")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "description~l10n")] #[serde(skip_serializing_if = "Option::is_none")] pub description_locale: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "fix-hint~l10n")] #[serde(skip_serializing_if = "Option::is_none")] pub fix_hint_locale: Option, } -#[derive(Debug, Clone, Deserialize, PartialEq)] +#[derive(Debug, Clone, Deserialize, PartialEq, TypedBuilder)] pub struct Description { + #[builder(default)] #[serde(flatten)] #[serde(skip_serializing_if = "HashMap::is_empty")] pub translations: HashMap, pub code: String, } - -impl Description { - pub fn new(code: String) -> Self { - Self { - translations: HashMap::new(), - code, - } - } -} - /// Manual implementation because `serde_json` does not support /// non-string map keys. impl Serialize for Description { @@ -214,7 +203,10 @@ mod tests { #[test] fn test_minimal_problem_report() { - let content = ProblemReportContent::new("test_problem_report_code".to_owned()); + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: ProblemReportContent = ProblemReportContent::builder().description(description).build(); let decorators = ProblemReportDecorators::default(); let expected = json!({ @@ -226,24 +218,30 @@ mod tests { #[test] fn test_extended_problem_report() { - let mut content = ProblemReportContent::new("test_problem_report_code".to_owned()); - content.who_retries = Some(WhoRetries::Me); - content.fix_hint = Some("test_fix_hint".to_owned()); - content.impact = Some(Impact::Connection); - content.location = Some(Where::new(WhereParty::Me, "test_location".to_owned())); - content.noticed_time = Some("test_noticed_time".to_owned()); - content.tracking_uri = Some("https://dummy.dummy/dummy".parse().unwrap()); - content.escalation_uri = Some("https://dummy.dummy/dummy".parse().unwrap()); - content.problem_items = Some(vec![HashMap::from([( - "test_prob_item_key".to_owned(), - "test_prob_item_value".to_owned(), - )])]); - - let mut decorators = ProblemReportDecorators::default(); - decorators.thread = Some(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); - decorators.description_locale = Some(make_extended_field_localization()); - decorators.fix_hint_locale = Some(make_extended_field_localization()); + let description = Description::builder() + .code("test_problem_report_code".to_owned()) + .build(); + let content: ProblemReportContent = ProblemReportContent::builder() + .description(description) + .who_retries(WhoRetries::Me) + .fix_hint("test_fix_hint".to_owned()) + .impact(Impact::Connection) + .location(Where::new(WhereParty::Me, "test_location".to_owned())) + .noticed_time("test_noticed_time".to_owned()) + .tracking_uri("https://dummy.dummy/dummy".parse().unwrap()) + .escalation_uri("https://dummy.dummy/dummy".parse().unwrap()) + .problem_items(vec![HashMap::from([( + "test_prob_item_key".to_owned(), + "test_prob_item_value".to_owned(), + )])]) + .build(); + + let decorators = ProblemReportDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .description_locale(make_extended_field_localization()) + .fix_hint_locale(make_extended_field_localization()) + .build(); let expected = json!({ "description": content.description, diff --git a/messages/src/msg_fields/protocols/revocation/ack.rs b/messages/src/msg_fields/protocols/revocation/ack.rs index 3ed054fef2..e3c32b2606 100644 --- a/messages/src/msg_fields/protocols/revocation/ack.rs +++ b/messages/src/msg_fields/protocols/revocation/ack.rs @@ -1,19 +1,32 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ - msg_fields::protocols::notification::ack::{AckContent, AckDecorators, AckStatus}, + msg_fields::protocols::notification::ack::{Ack, AckContent, AckDecorators}, msg_parts::MsgParts, }; pub type AckRevoke = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] #[serde(transparent)] -pub struct AckRevokeContent(pub AckContent); +pub struct AckRevokeContent { + pub inner: AckContent, +} + +impl From for AckRevokeContent { + fn from(value: AckContent) -> Self { + Self { inner: value } + } +} -impl AckRevokeContent { - pub fn new(status: AckStatus) -> Self { - Self(AckContent::new(status)) +impl From for Ack { + fn from(value: AckRevoke) -> Self { + Self::builder() + .id(value.id) + .content(value.content.inner) + .decorators(value.decorators) + .build() } } @@ -27,17 +40,18 @@ mod tests { use crate::{ decorators::{thread::tests::make_extended_thread, timing::tests::make_extended_timing}, misc::test_utils, + msg_fields::protocols::notification::ack::AckStatus, msg_types::revocation::RevocationTypeV2_0, }; #[test] fn test_minimal_ack_revoke() { - let content = AckRevokeContent::new(AckStatus::Ok); + let content: AckRevokeContent = AckContent::builder().status(AckStatus::Ok).build(); - let decorators = AckDecorators::new(make_extended_thread()); + let decorators = AckDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread }); @@ -46,13 +60,15 @@ mod tests { #[test] fn test_extended_ack_revoke() { - let content = AckRevokeContent::new(AckStatus::Ok); + let content: AckRevokeContent = AckContent::builder().status(AckStatus::Ok).build(); - let mut decorators = AckDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = AckDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ - "status": content.0.status, + "status": content.inner.status, "~thread": decorators.thread, "~timing": decorators.timing }); diff --git a/messages/src/msg_fields/protocols/revocation/revoke.rs b/messages/src/msg_fields/protocols/revocation/revoke.rs index 7304faed15..0bdca820de 100644 --- a/messages/src/msg_fields/protocols/revocation/revoke.rs +++ b/messages/src/msg_fields/protocols/revocation/revoke.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use shared_vcx::maybe_known::MaybeKnown; +use typed_builder::TypedBuilder; use crate::{ decorators::{please_ack::PleaseAck, thread::Thread, timing::Timing}, @@ -8,33 +9,27 @@ use crate::{ pub type Revoke = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct RevokeContent { pub credential_id: String, pub revocation_format: MaybeKnown, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, } -impl RevokeContent { - pub fn new(credential_id: String, revocation_format: MaybeKnown) -> Self { - Self { - credential_id, - revocation_format, - comment: None, - } - } -} - -#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct RevokeDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~please_ack")] #[serde(skip_serializing_if = "Option::is_none")] pub please_ack: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, @@ -59,10 +54,10 @@ mod tests { #[test] fn test_minimal_revoke() { - let content = RevokeContent::new( - "test_credential_id".to_owned(), - MaybeKnown::Known(RevocationFormat::IndyAnoncreds), - ); + let content = RevokeContent::builder() + .credential_id("test_credential_id".to_owned()) + .revocation_format(MaybeKnown::Known(RevocationFormat::IndyAnoncreds)) + .build(); let decorators = RevokeDecorators::default(); @@ -76,14 +71,13 @@ mod tests { #[test] fn test_extended_revoke() { - let mut content = RevokeContent::new( - "test_credential_id".to_owned(), - MaybeKnown::Known(RevocationFormat::IndyAnoncreds), - ); - content.comment = Some("test_comment".to_owned()); - - let mut decorators = RevokeDecorators::default(); - decorators.thread = Some(make_extended_thread()); + let content = RevokeContent::builder() + .credential_id("test_credential_id".to_owned()) + .revocation_format(MaybeKnown::Known(RevocationFormat::IndyAnoncreds)) + .comment("test_comment".to_owned()) + .build(); + + let decorators = RevokeDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "credential_id": content.credential_id, diff --git a/messages/src/msg_fields/protocols/routing.rs b/messages/src/msg_fields/protocols/routing.rs index 090d519f3a..887008ab91 100644 --- a/messages/src/msg_fields/protocols/routing.rs +++ b/messages/src/msg_fields/protocols/routing.rs @@ -2,23 +2,18 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; +use typed_builder::TypedBuilder; use crate::{misc::utils::into_msg_with_type, msg_parts::MsgParts, msg_types::protocols::routing::RoutingTypeV1_0}; pub type Forward = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct ForwardContent { pub to: String, pub msg: Value, } -impl ForwardContent { - pub fn new(to: String, msg: Value) -> Self { - Self { to, msg } - } -} - into_msg_with_type!(Forward, RoutingTypeV1_0, Forward); #[cfg(test)] @@ -34,7 +29,10 @@ mod tests { #[test] fn test_minimal_forward() { - let content = ForwardContent::new("test_to".to_owned(), json!("test_msg")); + let content = ForwardContent::builder() + .to("test_to".to_owned()) + .msg(json!("test_msg")) + .build(); let expected = json! ({ "to": content.to, diff --git a/messages/src/msg_fields/protocols/trust_ping/ping.rs b/messages/src/msg_fields/protocols/trust_ping/ping.rs index 1f7fc04eaf..a877307008 100644 --- a/messages/src/msg_fields/protocols/trust_ping/ping.rs +++ b/messages/src/msg_fields/protocols/trust_ping/ping.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -7,19 +8,23 @@ use crate::{ pub type Ping = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct PingContent { + #[builder(default)] #[serde(default)] pub response_requested: bool, + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, } -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct PingDecorators { + #[builder(default, setter(strip_option))] #[serde(rename = "~thread")] #[serde(skip_serializing_if = "Option::is_none")] pub thread: Option, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, @@ -51,11 +56,9 @@ mod tests { #[test] fn test_extended_ping() { - let mut content = PingContent::default(); - content.comment = Some("test_comment".to_owned()); + let content = PingContent::builder().comment("test_comment".to_owned()).build(); - let mut decorators = PingDecorators::default(); - decorators.thread = Some(make_extended_thread()); + let decorators = PingDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "response_requested": false, diff --git a/messages/src/msg_fields/protocols/trust_ping/ping_response.rs b/messages/src/msg_fields/protocols/trust_ping/ping_response.rs index a75e530c61..b69bb8f9ac 100644 --- a/messages/src/msg_fields/protocols/trust_ping/ping_response.rs +++ b/messages/src/msg_fields/protocols/trust_ping/ping_response.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; use crate::{ decorators::{thread::Thread, timing::Timing}, @@ -7,27 +8,23 @@ use crate::{ pub type PingResponse = MsgParts; -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] pub struct PingResponseContent { + #[builder(default, setter(strip_option))] #[serde(skip_serializing_if = "Option::is_none")] pub comment: Option, } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] pub struct PingResponseDecorators { #[serde(rename = "~thread")] pub thread: Thread, + #[builder(default, setter(strip_option))] #[serde(rename = "~timing")] #[serde(skip_serializing_if = "Option::is_none")] pub timing: Option, } -impl PingResponseDecorators { - pub fn new(thread: Thread) -> Self { - Self { thread, timing: None } - } -} - #[cfg(test)] #[allow(clippy::unwrap_used)] #[allow(clippy::field_reassign_with_default)] @@ -45,7 +42,7 @@ mod tests { fn test_minimal_ping_response() { let content = PingResponseContent::default(); - let decorators = PingResponseDecorators::new(make_extended_thread()); + let decorators = PingResponseDecorators::builder().thread(make_extended_thread()).build(); let expected = json!({ "~thread": decorators.thread @@ -56,11 +53,14 @@ mod tests { #[test] fn test_extended_ping_response() { - let mut content = PingResponseContent::default(); - content.comment = Some("test_comment".to_owned()); + let content = PingResponseContent::builder() + .comment("test_comment".to_owned()) + .build(); - let mut decorators = PingResponseDecorators::new(make_extended_thread()); - decorators.timing = Some(make_extended_timing()); + let decorators = PingResponseDecorators::builder() + .thread(make_extended_thread()) + .timing(make_extended_timing()) + .build(); let expected = json!({ "comment": content.comment, diff --git a/messages/src/msg_parts.rs b/messages/src/msg_parts.rs index 38c2ddc680..d5d5691c47 100644 --- a/messages/src/msg_parts.rs +++ b/messages/src/msg_parts.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; // Bind `shared_vcx::misc::serde_ignored::SerdeIgnored` type as `NoDecorators`. use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; +use typed_builder::TypedBuilder; /// Struct representing a complete message (apart from the `@type` field) as defined in a protocol /// RFC. The purpose of this type is to allow decomposition of certain message parts so they can be @@ -14,7 +15,8 @@ use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; /// `~attach` used in some messages that are in fact part of the protocol itself and are /// instrumental to the message processing, not an appendix to the message (such as `~thread` or /// `~timing`). -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] +#[builder(build_method(vis = "", name = __build))] pub struct MsgParts { /// All standalone messages have an `id` field. #[serde(rename = "@id")] @@ -27,22 +29,40 @@ pub struct MsgParts { pub decorators: D, } -impl MsgParts { - pub fn new(id: String, content: C) -> Self { - Self { - id, - content, - decorators: NoDecorators, - } +/// Allows building message without decorators being specified. +#[allow(dead_code, non_camel_case_types, missing_docs)] +impl MsgPartsBuilder +where + C: Default, +{ + pub fn build(self) -> T + where + MsgParts: Into, + { + self.content(Default::default()).__build().into() } } -impl MsgParts { - pub fn with_decorators(id: String, content: C, decorators: D) -> Self { - Self { - id, - content, - decorators, - } +/// Allows building message without decorators being specified. +#[allow(dead_code, non_camel_case_types, missing_docs)] +impl MsgPartsBuilder +where + D: Default, +{ + pub fn build(self) -> T + where + MsgParts: Into, + { + self.decorators(Default::default()).__build().into() + } +} + +#[allow(dead_code, non_camel_case_types, missing_docs)] +impl MsgPartsBuilder { + pub fn build(self) -> T + where + MsgParts: Into, + { + self.__build().into() } } diff --git a/wrappers/vcx-napi-rs/src/api/connection.rs b/wrappers/vcx-napi-rs/src/api/connection.rs index 4d2d13d4d5..946503f28a 100644 --- a/wrappers/vcx-napi-rs/src/api/connection.rs +++ b/wrappers/vcx-napi-rs/src/api/connection.rs @@ -145,13 +145,21 @@ pub async fn connection_send_ack(handle: u32) -> napi::Result<()> { pub async fn connection_send_generic_message(handle: u32, content: String) -> napi::Result<()> { trace!("connection_send_generic_message >>> handle: {:?}", handle); let id = Uuid::new_v4().to_string(); - let content = BasicMessageContent::new(content, Utc::now()); - let mut decorators = BasicMessageDecorators::default(); - let mut timing = Timing::default(); - timing.out_time = Some(Utc::now()); - decorators.timing = Some(timing); - - let message = AriesMessage::from(BasicMessage::with_decorators(id, content, decorators)); + let content = BasicMessageContent::builder() + .content(content) + .sent_time(Utc::now()) + .build(); + let decorators = BasicMessageDecorators::builder() + .timing(Timing::builder().out_time(Utc::now()).build()) + .build(); + + let message: BasicMessage = BasicMessage::builder() + .id(id) + .content(content) + .decorators(decorators) + .build(); + + let message = AriesMessage::from(message); let basic_message = serde_json::to_string(&message) .map_err(From::from)