From d5ffa6c5c2c3430a19c801189ed745215fe7508a Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Fri, 2 Jun 2023 15:31:16 +0200 Subject: [PATCH] Improve service struct builder Signed-off-by: Miroslav Kovar --- did_doc/src/schema/did_doc.rs | 4 +- did_doc/src/schema/service.rs | 84 ++++++++++++++------- did_resolver_sov/src/dereferencing/utils.rs | 12 +-- did_resolver_sov/src/resolution/utils.rs | 17 +++-- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/did_doc/src/schema/did_doc.rs b/did_doc/src/schema/did_doc.rs index 60b0729425..a3dd20641a 100644 --- a/did_doc/src/schema/did_doc.rs +++ b/did_doc/src/schema/did_doc.rs @@ -268,11 +268,9 @@ mod tests { let service_type = "test-service".to_string(); let service_endpoint = "https://example.com/service"; let service = ServiceBuilder::<()>::new(service_id, service_endpoint.try_into().unwrap()) - .unwrap() .add_service_type(service_type) .unwrap() - .build() - .unwrap(); + .build(); let document = DidDocumentBuilder::new(id.clone()) .add_also_known_as(also_known_as.clone()) diff --git a/did_doc/src/schema/service.rs b/did_doc/src/schema/service.rs index 0764d7c982..4429c62f15 100644 --- a/did_doc/src/schema/service.rs +++ b/did_doc/src/schema/service.rs @@ -29,10 +29,7 @@ impl Service where E: Default, { - pub fn builder( - id: Uri, - service_endpoint: Url, - ) -> Result, DidDocumentBuilderError> { + pub fn builder(id: Uri, service_endpoint: Url) -> ServiceBuilder { ServiceBuilder::new(id, service_endpoint) } @@ -55,6 +52,13 @@ where #[derive(Debug)] pub struct ServiceBuilder { + id: Uri, + service_endpoint: Url, + extra: E, +} + +#[derive(Debug)] +pub struct ServiceBuilderWithServiceType { id: Uri, service_type: HashSet, service_endpoint: Url, @@ -65,15 +69,52 @@ impl ServiceBuilder where E: Default, { - pub fn new(id: Uri, service_endpoint: Url) -> Result { - Ok(Self { + pub fn new(id: Uri, service_endpoint: Url) -> Self { + Self { id, service_endpoint, - service_type: HashSet::new(), extra: E::default(), + } + } + + pub fn add_service_type( + self, + service_type: String, + ) -> Result, DidDocumentBuilderError> { + if service_type.is_empty() { + return Err(DidDocumentBuilderError::MissingField("type")); + } + let mut service_types = HashSet::new(); + service_types.insert(service_type); + Ok(ServiceBuilderWithServiceType { + id: self.id, + service_type: service_types, + service_endpoint: self.service_endpoint, + extra: self.extra, }) } + pub fn add_service_types( + self, + service_types: Vec, + ) -> Result, DidDocumentBuilderError> { + if service_types.is_empty() { + return Err(DidDocumentBuilderError::MissingField("type")); + } + let service_types = service_types.into_iter().collect::>(); + Ok(ServiceBuilderWithServiceType { + id: self.id, + service_type: service_types, + service_endpoint: self.service_endpoint, + extra: self.extra, + }) + } +} + +impl ServiceBuilderWithServiceType +where + E: Default, +{ pub fn add_service_type( mut self, service_type: String, @@ -90,16 +131,12 @@ where self } - pub fn build(self) -> Result, DidDocumentBuilderError> { - if self.service_type.is_empty() { - Err(DidDocumentBuilderError::MissingField("type")) - } else { - Ok(Service { - id: self.id, - service_type: OneOrList::List(self.service_type.into_iter().collect()), - service_endpoint: self.service_endpoint, - extra: self.extra, - }) + pub fn build(self) -> Service { + Service { + id: self.id, + service_type: OneOrList::List(self.service_type.into_iter().collect()), + service_endpoint: self.service_endpoint, + extra: self.extra, } } } @@ -128,11 +165,9 @@ mod tests { let service = ServiceBuilder::::new(id.clone(), service_endpoint.try_into().unwrap()) - .unwrap() .add_service_type(service_type.clone()) .unwrap() - .build() - .unwrap(); + .build(); assert_eq!(service.id(), &id); assert_eq!(service.service_endpoint().as_ref(), service_endpoint); @@ -153,12 +188,10 @@ mod tests { }; let service = ServiceBuilder::::new(id, service_endpoint.try_into().unwrap()) - .unwrap() .add_service_type(service_type) .unwrap() .add_extra(extra) - .build() - .unwrap(); + .build(); assert_eq!(service.extra().recipient_keys, recipient_keys); assert_eq!(service.extra().routing_keys, routing_keys); @@ -171,13 +204,11 @@ mod tests { let service_type = "DIDCommMessaging".to_string(); let service = ServiceBuilder::::new(id, service_endpoint.try_into().unwrap()) - .unwrap() .add_service_type(service_type.clone()) .unwrap() .add_service_type(service_type.clone()) .unwrap() - .build() - .unwrap(); + .build(); assert_eq!(service.service_type(), &OneOrList::List(vec![service_type])); } @@ -188,7 +219,6 @@ mod tests { let service_endpoint = "http://example.com/endpoint"; let res = ServiceBuilder::::new(id, service_endpoint.try_into().unwrap()) - .unwrap() .add_service_type("".to_string()); assert!(res.is_err()); } diff --git a/did_resolver_sov/src/dereferencing/utils.rs b/did_resolver_sov/src/dereferencing/utils.rs index cbcb2f5a72..46791ee3f8 100644 --- a/did_resolver_sov/src/dereferencing/utils.rs +++ b/did_resolver_sov/src/dereferencing/utils.rs @@ -117,21 +117,17 @@ mod tests { "did:example:123456789abcdefghi#agent".parse().unwrap(), "https://agent.example.com/8377464".try_into().unwrap(), ) - .unwrap() .add_service_type("AgentService".to_string()) .unwrap() - .build() - .unwrap(); + .build(); let messaging_service = Service::builder( "did:example:123456789abcdefghi#messages".parse().unwrap(), "https://example.com/messages/8377464".try_into().unwrap(), ) - .unwrap() .add_service_type("MessagingService".to_string()) .unwrap() - .build() - .unwrap(); + .build(); DidDocument::builder(Default::default()) .add_verification_method(verification_method) @@ -207,11 +203,9 @@ mod tests { "did:example:123456789abcdefghi#keys-1".parse().unwrap(), "https://example.com/duplicated/8377464".try_into().unwrap(), ) - .unwrap() .add_service_type("DuplicatedService".to_string()) .unwrap() - .build() - .unwrap(); + .build(); did_document_builder.add_service(additional_service).build() }; diff --git a/did_resolver_sov/src/resolution/utils.rs b/did_resolver_sov/src/resolution/utils.rs index 76f5f25d9e..2a909bf594 100644 --- a/did_resolver_sov/src/resolution/utils.rs +++ b/did_resolver_sov/src/resolution/utils.rs @@ -73,14 +73,15 @@ pub(super) async fn ledger_response_to_ddo( let datetime = unix_to_datetime(txn_time); let service = { - let mut service_builder = - Service::builder(service_id, endpoint.endpoint.as_str().try_into()?)?; - for t in endpoint.types { - if t != DidSovServiceType::Unknown { - service_builder = service_builder.add_service_type(t.to_string())?; - }; - } - service_builder.build()? + let service_types: Vec = endpoint + .types + .into_iter() + .filter(|t| *t != DidSovServiceType::Unknown) + .map(|t| t.to_string()) + .collect(); + Service::builder(service_id, endpoint.endpoint.as_str().try_into()?) + .add_service_types(service_types)? + .build() }; // TODO: Use multibase instead of base58