1use core::fmt;
4use core::mem;
5use core::str::FromStr;
6use std::borrow::Cow;
7use std::collections::{HashMap, HashSet};
8
9use indexmap::{IndexMap, IndexSet};
10use serde::de::{self, MapAccess, SeqAccess, Visitor};
11use serde::ser::SerializeMap as _;
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13use serde_json::Value;
14
15use super::{Did, DidUrl, DidUrlReference, Uri};
16use crate::jose::{Jwk, OneOrMany};
17
18#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
20#[non_exhaustive]
21pub enum DocumentError {
22 #[error("`@context` must be a string, a map or a non-empty array")]
24 InvalidContext,
25 #[error("verification method `{0}` already exists")]
28 DuplicateVerificationMethod(DidUrl),
29 #[error("service `{0}` already exists")]
31 DuplicateService(DidUrl),
32 #[error("verification method `{0}` not found")]
34 VerificationMethodNotFound(DidUrl),
35 #[error("`{url}` does not belong to document `{document}`")]
37 ForeignDid {
38 url: DidUrl,
40 document: Did,
42 },
43 #[error("verification method `{id}` is not listed under `{relationship}`")]
45 NotInRelationship {
46 id: DidUrl,
48 relationship: VerificationRelationship,
50 },
51 #[error("unknown verification relationship `{0}`")]
53 UnknownRelationship(String),
54 #[error("`{0}` is a core property, not an extension property")]
56 ReservedProperty(String),
57}
58
59#[expect(clippy::ref_option, reason = "serde passes the field by reference")]
65fn is_none_or_empty<T>(value: &Option<OneOrMany<T>>) -> bool {
66 value.as_ref().is_none_or(OneOrMany::is_empty)
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
88#[serde(transparent)]
89pub struct Context(Value);
90
91impl Context {
92 pub const DID_V1: &'static str = "https://www.w3.org/ns/did/v1";
94
95 pub fn did_v1() -> Self {
97 Self::uri(Self::DID_V1)
98 }
99
100 pub fn uri(uri: impl Into<String>) -> Self {
102 Self(Value::String(uri.into()))
103 }
104
105 pub fn uris<I, S>(uris: I) -> Self
107 where
108 I: IntoIterator<Item = S>,
109 S: Into<String>,
110 {
111 Self(Value::Array(
112 uris.into_iter().map(|s| Value::String(s.into())).collect(),
113 ))
114 }
115
116 pub fn new(value: Value) -> Result<Self, DocumentError> {
122 match &value {
123 Value::String(_) | Value::Object(_) => Ok(Self(value)),
124 Value::Array(items) if !items.is_empty() => Ok(Self(value)),
125 _ => Err(DocumentError::InvalidContext),
126 }
127 }
128
129 pub fn as_value(&self) -> &Value {
131 &self.0
132 }
133
134 pub fn into_value(self) -> Value {
136 self.0
137 }
138
139 pub fn contains(&self, uri: &str) -> bool {
141 match &self.0 {
142 Value::String(s) => s == uri,
143 Value::Array(items) => items.iter().any(|item| item.as_str() == Some(uri)),
144 _ => false,
145 }
146 }
147}
148
149impl<'de> Deserialize<'de> for Context {
150 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
151 Self::new(Value::deserialize(deserializer)?).map_err(de::Error::custom)
152 }
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub enum VerificationRelationship {
160 Authentication,
162 AssertionMethod,
164 KeyAgreement,
166 CapabilityInvocation,
168 CapabilityDelegation,
170}
171
172impl VerificationRelationship {
173 pub const ALL: &'static [VerificationRelationship] = &[
175 Self::Authentication,
176 Self::AssertionMethod,
177 Self::KeyAgreement,
178 Self::CapabilityInvocation,
179 Self::CapabilityDelegation,
180 ];
181
182 pub const fn as_str(self) -> &'static str {
184 match self {
185 Self::Authentication => "authentication",
186 Self::AssertionMethod => "assertionMethod",
187 Self::KeyAgreement => "keyAgreement",
188 Self::CapabilityInvocation => "capabilityInvocation",
189 Self::CapabilityDelegation => "capabilityDelegation",
190 }
191 }
192}
193
194impl fmt::Display for VerificationRelationship {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 f.write_str(self.as_str())
197 }
198}
199
200impl FromStr for VerificationRelationship {
201 type Err = DocumentError;
202
203 fn from_str(s: &str) -> Result<Self, Self::Err> {
204 Self::ALL
205 .iter()
206 .copied()
207 .find(|rel| rel.as_str() == s)
208 .ok_or_else(|| DocumentError::UnknownRelationship(s.to_owned()))
209 }
210}
211
212#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
226pub struct MethodType(Cow<'static, str>);
227
228impl MethodType {
229 pub const JSON_WEB_KEY_2020: MethodType = MethodType(Cow::Borrowed("JsonWebKey2020"));
231 pub const JSON_WEB_KEY: MethodType = MethodType(Cow::Borrowed("JsonWebKey"));
233 pub const MULTIKEY: MethodType = MethodType(Cow::Borrowed("Multikey"));
235 pub const ED25519_VERIFICATION_KEY_2020: MethodType =
237 MethodType(Cow::Borrowed("Ed25519VerificationKey2020"));
238
239 pub fn new(name: impl Into<String>) -> Self {
241 Self(Cow::Owned(name.into()))
242 }
243
244 pub fn as_str(&self) -> &str {
246 &self.0
247 }
248}
249
250impl fmt::Debug for MethodType {
251 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252 fmt::Debug::fmt(self.as_str(), f)
253 }
254}
255
256impl fmt::Display for MethodType {
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 f.write_str(self.as_str())
259 }
260}
261
262impl From<&str> for MethodType {
263 fn from(name: &str) -> Self {
264 Self::new(name)
265 }
266}
267
268impl From<String> for MethodType {
269 fn from(name: String) -> Self {
270 Self::new(name)
271 }
272}
273
274impl PartialEq<str> for MethodType {
275 fn eq(&self, other: &str) -> bool {
276 self.as_str() == other
277 }
278}
279
280impl PartialEq<&str> for MethodType {
281 fn eq(&self, other: &&str) -> bool {
282 self.as_str() == *other
283 }
284}
285
286impl Serialize for MethodType {
287 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
288 serializer.serialize_str(self.as_str())
289 }
290}
291
292impl<'de> Deserialize<'de> for MethodType {
293 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
294 String::deserialize(deserializer).map(Self::new)
295 }
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
308#[non_exhaustive]
309pub enum VerificationMaterial {
310 PublicKeyJwk(Box<Jwk>),
312 PublicKeyMultibase(String),
314}
315
316impl VerificationMaterial {
317 pub fn jwk(jwk: &Jwk) -> Self {
319 Self::PublicKeyJwk(Box::new(jwk.public()))
320 }
321
322 pub fn multibase(value: impl Into<String>) -> Self {
324 Self::PublicKeyMultibase(value.into())
325 }
326
327 pub fn as_jwk(&self) -> Option<&Jwk> {
329 match self {
330 Self::PublicKeyJwk(jwk) => Some(jwk),
331 Self::PublicKeyMultibase(_) => None,
332 }
333 }
334
335 pub fn as_multibase(&self) -> Option<&str> {
337 match self {
338 Self::PublicKeyMultibase(value) => Some(value),
339 Self::PublicKeyJwk(_) => None,
340 }
341 }
342}
343
344impl Serialize for VerificationMaterial {
345 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
346 let mut map = serializer.serialize_map(Some(1))?;
347 match self {
348 Self::PublicKeyJwk(jwk) => {
349 if jwk.is_private() {
350 return Err(serde::ser::Error::custom(
351 "`publicKeyJwk` must not contain private parameters",
352 ));
353 }
354 map.serialize_entry("publicKeyJwk", jwk)?;
355 }
356 Self::PublicKeyMultibase(value) => map.serialize_entry("publicKeyMultibase", value)?,
357 }
358 map.end()
359 }
360}
361
362#[derive(Deserialize)]
364struct MaterialMembers {
365 #[serde(rename = "publicKeyJwk", default)]
366 public_key_jwk: Option<Jwk>,
367 #[serde(rename = "publicKeyMultibase", default)]
368 public_key_multibase: Option<String>,
369}
370
371impl<'de> Deserialize<'de> for VerificationMaterial {
372 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
373 let members = MaterialMembers::deserialize(deserializer)?;
374 match (members.public_key_jwk, members.public_key_multibase) {
375 (Some(jwk), None) if jwk.is_private() => Err(de::Error::custom(
376 "`publicKeyJwk` must not contain private parameters",
377 )),
378 (Some(jwk), None) => Ok(Self::PublicKeyJwk(Box::new(jwk))),
379 (None, Some(value)) => Ok(Self::PublicKeyMultibase(value)),
380 (None, None) => Err(de::Error::custom(
381 "verification method has neither `publicKeyJwk` nor `publicKeyMultibase`",
382 )),
383 (Some(_), Some(_)) => Err(de::Error::custom(
384 "verification method has both `publicKeyJwk` and `publicKeyMultibase`",
385 )),
386 }
387 }
388}
389
390#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
415#[non_exhaustive]
416pub struct VerificationMethod {
417 pub id: DidUrl,
419 #[serde(rename = "type")]
421 pub method_type: MethodType,
422 pub controller: Did,
424 #[serde(flatten)]
426 pub material: VerificationMaterial,
427 #[serde(flatten)]
429 pub properties: IndexMap<String, Value>,
430}
431
432impl VerificationMethod {
433 pub fn new(
435 id: DidUrl,
436 method_type: MethodType,
437 controller: Did,
438 material: VerificationMaterial,
439 ) -> Self {
440 Self {
441 id,
442 method_type,
443 controller,
444 material,
445 properties: IndexMap::new(),
446 }
447 }
448
449 pub fn public_key_jwk(&self) -> Option<&Jwk> {
451 self.material.as_jwk()
452 }
453
454 pub fn public_key_multibase(&self) -> Option<&str> {
456 self.material.as_multibase()
457 }
458}
459
460#[derive(Debug, Clone, PartialEq, Eq)]
463pub enum MethodRef {
464 Reference(DidUrlReference),
466 Embedded(Box<VerificationMethod>),
468}
469
470impl MethodRef {
471 pub fn reference(id: impl Into<DidUrlReference>) -> Self {
473 Self::Reference(id.into())
474 }
475
476 pub fn embedded(method: VerificationMethod) -> Self {
478 Self::Embedded(Box::new(method))
479 }
480
481 pub fn as_embedded(&self) -> Option<&VerificationMethod> {
483 match self {
484 Self::Embedded(method) => Some(method),
485 Self::Reference(_) => None,
486 }
487 }
488
489 pub fn as_reference(&self) -> Option<&DidUrlReference> {
491 match self {
492 Self::Reference(reference) => Some(reference),
493 Self::Embedded(_) => None,
494 }
495 }
496
497 pub fn refers_to(&self, id: &DidUrl, base: &Did) -> bool {
499 match self {
500 Self::Reference(reference) => reference.refers_to(id, base),
501 Self::Embedded(method) => method.id == *id,
502 }
503 }
504}
505
506impl From<DidUrl> for MethodRef {
507 fn from(id: DidUrl) -> Self {
508 Self::Reference(id.into())
509 }
510}
511
512impl From<DidUrlReference> for MethodRef {
513 fn from(reference: DidUrlReference) -> Self {
514 Self::Reference(reference)
515 }
516}
517
518impl From<VerificationMethod> for MethodRef {
519 fn from(method: VerificationMethod) -> Self {
520 Self::embedded(method)
521 }
522}
523
524impl Serialize for MethodRef {
525 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
526 match self {
527 Self::Reference(reference) => reference.serialize(serializer),
528 Self::Embedded(method) => method.serialize(serializer),
529 }
530 }
531}
532
533impl<'de> Deserialize<'de> for MethodRef {
534 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
535 struct MethodRefVisitor;
536
537 impl<'de> Visitor<'de> for MethodRefVisitor {
538 type Value = MethodRef;
539
540 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
541 f.write_str("a DID URL string or a verification method object")
542 }
543
544 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
545 DidUrlReference::parse(value)
546 .map(MethodRef::Reference)
547 .map_err(E::custom)
548 }
549
550 fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
551 VerificationMethod::deserialize(de::value::MapAccessDeserializer::new(map))
552 .map(MethodRef::embedded)
553 }
554 }
555
556 deserializer.deserialize_any(MethodRefVisitor)
557 }
558}
559
560#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
566#[serde(untagged)]
567pub enum ServiceEndpoint {
568 Uri(Uri),
570 Set(IndexSet<Uri>),
572 Map(IndexMap<String, Value>),
574}
575
576impl ServiceEndpoint {
577 pub fn uri(uri: Uri) -> Self {
579 Self::Uri(uri)
580 }
581
582 pub fn uris(&self) -> impl Iterator<Item = &Uri> {
584 let slice: Box<dyn Iterator<Item = &Uri>> = match self {
585 Self::Uri(uri) => Box::new(core::iter::once(uri)),
586 Self::Set(set) => Box::new(set.iter()),
587 Self::Map(_) => Box::new(core::iter::empty()),
588 };
589 slice
590 }
591}
592
593impl From<Uri> for ServiceEndpoint {
594 fn from(uri: Uri) -> Self {
595 Self::Uri(uri)
596 }
597}
598
599impl<'de> Deserialize<'de> for ServiceEndpoint {
600 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
601 struct EndpointVisitor;
602
603 impl<'de> Visitor<'de> for EndpointVisitor {
604 type Value = ServiceEndpoint;
605
606 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
607 f.write_str("a URI string, a non-empty array of URI strings, or an object")
608 }
609
610 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
611 Uri::parse(value)
612 .map(ServiceEndpoint::Uri)
613 .map_err(E::custom)
614 }
615
616 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
617 let mut set = IndexSet::new();
618 while let Some(uri) = seq.next_element::<Uri>()? {
619 set.insert(uri);
620 }
621 if set.is_empty() {
622 return Err(de::Error::custom(
623 "`serviceEndpoint` set must contain at least one URI",
624 ));
625 }
626 Ok(ServiceEndpoint::Set(set))
627 }
628
629 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
630 let mut entries = IndexMap::new();
631 while let Some((key, value)) = map.next_entry::<String, Value>()? {
632 entries.insert(key, value);
633 }
634 Ok(ServiceEndpoint::Map(entries))
635 }
636 }
637
638 deserializer.deserialize_any(EndpointVisitor)
639 }
640}
641
642#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
647#[non_exhaustive]
648pub struct Service {
649 pub id: DidUrl,
651 #[serde(rename = "type")]
653 pub service_type: OneOrMany<String>,
654 #[serde(rename = "serviceEndpoint")]
656 pub service_endpoint: ServiceEndpoint,
657 #[serde(flatten)]
659 pub properties: IndexMap<String, Value>,
660}
661
662impl Service {
663 pub fn new(
665 id: DidUrl,
666 service_type: impl Into<OneOrMany<String>>,
667 service_endpoint: impl Into<ServiceEndpoint>,
668 ) -> Self {
669 Self {
670 id,
671 service_type: service_type.into(),
672 service_endpoint: service_endpoint.into(),
673 properties: IndexMap::new(),
674 }
675 }
676
677 pub fn has_type(&self, service_type: &str) -> bool {
679 self.service_type.iter().any(|t| t == service_type)
680 }
681}
682
683#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
733#[non_exhaustive]
734#[serde(remote = "Self")]
735pub struct DidDocument {
736 #[serde(rename = "@context", default, skip_serializing_if = "Option::is_none")]
738 pub context: Option<Context>,
739 pub id: Did,
741 #[serde(rename = "alsoKnownAs", default, skip_serializing_if = "Vec::is_empty")]
743 pub also_known_as: Vec<Uri>,
744 #[serde(default, skip_serializing_if = "is_none_or_empty")]
747 pub controller: Option<OneOrMany<Did>>,
748 #[serde(
750 rename = "verificationMethod",
751 default,
752 skip_serializing_if = "Vec::is_empty"
753 )]
754 pub verification_method: Vec<VerificationMethod>,
755 #[serde(default, skip_serializing_if = "Vec::is_empty")]
757 pub authentication: Vec<MethodRef>,
758 #[serde(
760 rename = "assertionMethod",
761 default,
762 skip_serializing_if = "Vec::is_empty"
763 )]
764 pub assertion_method: Vec<MethodRef>,
765 #[serde(
767 rename = "keyAgreement",
768 default,
769 skip_serializing_if = "Vec::is_empty"
770 )]
771 pub key_agreement: Vec<MethodRef>,
772 #[serde(
774 rename = "capabilityInvocation",
775 default,
776 skip_serializing_if = "Vec::is_empty"
777 )]
778 pub capability_invocation: Vec<MethodRef>,
779 #[serde(
781 rename = "capabilityDelegation",
782 default,
783 skip_serializing_if = "Vec::is_empty"
784 )]
785 pub capability_delegation: Vec<MethodRef>,
786 #[serde(default, skip_serializing_if = "Vec::is_empty")]
788 pub service: Vec<Service>,
789 #[serde(flatten)]
791 pub properties: IndexMap<String, Value>,
792}
793
794impl Serialize for DidDocument {
795 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
796 Self::serialize(self, serializer)
797 }
798}
799
800impl<'de> Deserialize<'de> for DidDocument {
801 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
804 let mut document = Self::deserialize(deserializer)?;
805 document.check_unique_ids().map_err(de::Error::custom)?;
806 if is_none_or_empty(&document.controller) {
807 document.controller = None;
808 }
809 Ok(document)
810 }
811}
812
813impl DidDocument {
814 pub const CORE_PROPERTIES: &'static [&'static str] = &[
816 "@context",
817 "id",
818 "alsoKnownAs",
819 "controller",
820 "verificationMethod",
821 "authentication",
822 "assertionMethod",
823 "keyAgreement",
824 "capabilityInvocation",
825 "capabilityDelegation",
826 "service",
827 ];
828
829 pub fn new(id: Did) -> Self {
831 Self {
832 context: None,
833 id,
834 also_known_as: Vec::new(),
835 controller: None,
836 verification_method: Vec::new(),
837 authentication: Vec::new(),
838 assertion_method: Vec::new(),
839 key_agreement: Vec::new(),
840 capability_invocation: Vec::new(),
841 capability_delegation: Vec::new(),
842 service: Vec::new(),
843 properties: IndexMap::new(),
844 }
845 }
846
847 pub fn builder(id: Did) -> DidDocumentBuilder {
849 DidDocumentBuilder {
850 document: Self::new(id),
851 error: None,
852 }
853 }
854
855 pub fn relationship(&self, relationship: VerificationRelationship) -> &[MethodRef] {
857 match relationship {
858 VerificationRelationship::Authentication => &self.authentication,
859 VerificationRelationship::AssertionMethod => &self.assertion_method,
860 VerificationRelationship::KeyAgreement => &self.key_agreement,
861 VerificationRelationship::CapabilityInvocation => &self.capability_invocation,
862 VerificationRelationship::CapabilityDelegation => &self.capability_delegation,
863 }
864 }
865
866 pub fn relationship_mut(
868 &mut self,
869 relationship: VerificationRelationship,
870 ) -> &mut Vec<MethodRef> {
871 match relationship {
872 VerificationRelationship::Authentication => &mut self.authentication,
873 VerificationRelationship::AssertionMethod => &mut self.assertion_method,
874 VerificationRelationship::KeyAgreement => &mut self.key_agreement,
875 VerificationRelationship::CapabilityInvocation => &mut self.capability_invocation,
876 VerificationRelationship::CapabilityDelegation => &mut self.capability_delegation,
877 }
878 }
879
880 fn embedded_methods(&self) -> impl Iterator<Item = &VerificationMethod> {
882 VerificationRelationship::ALL
883 .iter()
884 .flat_map(|rel| self.relationship(*rel))
885 .filter_map(MethodRef::as_embedded)
886 }
887
888 pub fn verification_method(&self, id: &DidUrl) -> Option<&VerificationMethod> {
891 self.verification_method
892 .iter()
893 .chain(self.embedded_methods())
894 .find(|method| method.id == *id)
895 }
896
897 pub fn methods(
903 &self,
904 relationship: Option<VerificationRelationship>,
905 ) -> impl Iterator<Item = &VerificationMethod> {
906 let entries: Box<dyn Iterator<Item = &VerificationMethod>> =
907 match relationship {
908 None => Box::new(
909 self.verification_method
910 .iter()
911 .chain(self.embedded_methods()),
912 ),
913 Some(rel) => Box::new(self.relationship(rel).iter().filter_map(
914 |entry| match entry {
915 MethodRef::Embedded(method) => Some(&**method),
916 MethodRef::Reference(reference) => {
917 let id = reference.resolve(&self.id).ok()?;
918 self.verification_method.iter().find(|m| m.id == id)
919 }
920 },
921 )),
922 };
923 entries
924 }
925
926 pub fn resolve_verification_method(
938 &self,
939 id: &DidUrl,
940 relationship: Option<VerificationRelationship>,
941 ) -> Result<&VerificationMethod, DocumentError> {
942 if id.did() != &self.id {
943 return Err(DocumentError::ForeignDid {
944 url: id.clone(),
945 document: self.id.clone(),
946 });
947 }
948 let Some(relationship) = relationship else {
949 return self
950 .verification_method(id)
951 .ok_or_else(|| DocumentError::VerificationMethodNotFound(id.clone()));
952 };
953 for entry in self.relationship(relationship) {
954 match entry {
955 MethodRef::Embedded(method) if method.id == *id => return Ok(method),
956 MethodRef::Reference(reference) if reference.refers_to(id, &self.id) => {
957 return self
958 .verification_method
959 .iter()
960 .find(|method| method.id == *id)
961 .ok_or_else(|| DocumentError::VerificationMethodNotFound(id.clone()));
962 }
963 _ => {}
964 }
965 }
966 if self.verification_method(id).is_some() {
967 Err(DocumentError::NotInRelationship {
968 id: id.clone(),
969 relationship,
970 })
971 } else {
972 Err(DocumentError::VerificationMethodNotFound(id.clone()))
973 }
974 }
975
976 pub fn resolve_method_reference(
983 &self,
984 reference: &DidUrlReference,
985 relationship: Option<VerificationRelationship>,
986 ) -> Result<&VerificationMethod, DocumentError> {
987 let id = reference.resolve(&self.id).map_err(|_| match reference {
989 DidUrlReference::Absolute(url) => DocumentError::ForeignDid {
990 url: url.clone(),
991 document: self.id.clone(),
992 },
993 DidUrlReference::Relative(_) => {
994 DocumentError::VerificationMethodNotFound(self.id.to_url())
995 }
996 })?;
997 self.resolve_verification_method(&id, relationship)
998 }
999
1000 pub fn insert_verification_method(
1007 &mut self,
1008 method: VerificationMethod,
1009 relationships: impl IntoIterator<Item = VerificationRelationship>,
1010 ) -> Result<(), DocumentError> {
1011 if self.verification_method(&method.id).is_some() {
1012 return Err(DocumentError::DuplicateVerificationMethod(method.id));
1013 }
1014 let id = method.id.clone();
1015 self.verification_method.push(method);
1016 for relationship in relationships {
1017 self.attach_relationship(&id, relationship)?;
1018 }
1019 Ok(())
1020 }
1021
1022 pub fn check_unique_ids(&self) -> Result<(), DocumentError> {
1032 let mut seen = HashMap::new();
1033 for method in self
1034 .verification_method
1035 .iter()
1036 .chain(self.embedded_methods())
1037 {
1038 if *seen.entry(&method.id).or_insert(method) != method {
1039 return Err(DocumentError::DuplicateVerificationMethod(
1040 method.id.clone(),
1041 ));
1042 }
1043 }
1044 let mut seen = HashSet::new();
1045 for service in &self.service {
1046 if !seen.insert(&service.id) {
1047 return Err(DocumentError::DuplicateService(service.id.clone()));
1048 }
1049 }
1050 Ok(())
1051 }
1052
1053 pub fn remove_verification_method(&mut self, id: &DidUrl) -> Option<VerificationMethod> {
1055 let (matching, rest): (Vec<_>, Vec<_>) = mem::take(&mut self.verification_method)
1057 .into_iter()
1058 .partition(|method| method.id == *id);
1059 self.verification_method = rest;
1060 let listed = matching.into_iter().next();
1061 let mut embedded = None;
1062 let base = self.id.clone();
1063 for relationship in VerificationRelationship::ALL {
1064 let entries = self.relationship_mut(*relationship);
1065 let mut index = 0;
1066 while index < entries.len() {
1067 if entries[index].refers_to(id, &base) {
1068 if let MethodRef::Embedded(method) = entries.remove(index) {
1069 embedded.get_or_insert(*method);
1070 }
1071 } else {
1072 index += 1;
1073 }
1074 }
1075 }
1076 listed.or(embedded)
1077 }
1078
1079 pub fn attach_relationship(
1089 &mut self,
1090 id: &DidUrl,
1091 relationship: VerificationRelationship,
1092 ) -> Result<bool, DocumentError> {
1093 if !self.verification_method.iter().any(|m| m.id == *id) {
1094 return Err(DocumentError::VerificationMethodNotFound(id.clone()));
1095 }
1096 let base = self.id.clone();
1097 let entries = self.relationship_mut(relationship);
1098 if entries.iter().any(|entry| entry.refers_to(id, &base)) {
1099 return Ok(false);
1100 }
1101 entries.push(MethodRef::Reference(id.clone().into()));
1102 Ok(true)
1103 }
1104
1105 pub fn detach_relationship(
1108 &mut self,
1109 id: &DidUrl,
1110 relationship: VerificationRelationship,
1111 ) -> bool {
1112 let base = self.id.clone();
1113 let entries = self.relationship_mut(relationship);
1114 let before = entries.len();
1115 entries.retain(|entry| !entry.refers_to(id, &base));
1116 entries.len() != before
1117 }
1118
1119 pub fn service(&self, id: &DidUrl) -> Option<&Service> {
1121 self.service.iter().find(|service| service.id == *id)
1122 }
1123
1124 pub fn insert_service(&mut self, service: Service) -> Result<(), DocumentError> {
1130 if self.service(&service.id).is_some() {
1131 return Err(DocumentError::DuplicateService(service.id));
1132 }
1133 self.service.push(service);
1134 Ok(())
1135 }
1136
1137 pub fn remove_service(&mut self, id: &DidUrl) -> Option<Service> {
1139 self.service
1140 .iter()
1141 .position(|service| service.id == *id)
1142 .map(|index| self.service.remove(index))
1143 }
1144
1145 pub fn map_dids(&mut self, mut f: impl FnMut(Did) -> Did) {
1185 fn map_url(url: &mut DidUrl, f: &mut impl FnMut(Did) -> Did) {
1186 let did = f(url.did().clone());
1187 if &did != url.did() {
1188 *url = url.with_did(did);
1189 }
1190 }
1191 fn map_method(method: &mut VerificationMethod, f: &mut impl FnMut(Did) -> Did) {
1192 map_url(&mut method.id, f);
1193 method.controller = f(method.controller.clone());
1194 }
1195
1196 self.id = f(self.id.clone());
1197 if let Some(controller) = &mut self.controller {
1198 for did in controller.iter_mut() {
1199 *did = f(did.clone());
1200 }
1201 }
1202 for method in &mut self.verification_method {
1203 map_method(method, &mut f);
1204 }
1205 for relationship in VerificationRelationship::ALL {
1206 for entry in self.relationship_mut(*relationship) {
1207 match entry {
1208 MethodRef::Reference(DidUrlReference::Absolute(url)) => map_url(url, &mut f),
1209 MethodRef::Reference(DidUrlReference::Relative(_)) => {}
1210 MethodRef::Embedded(method) => map_method(method, &mut f),
1211 }
1212 }
1213 }
1214 for service in &mut self.service {
1215 map_url(&mut service.id, &mut f);
1216 }
1217 }
1218}
1219
1220#[derive(Debug, Clone)]
1222pub struct DidDocumentBuilder {
1223 document: DidDocument,
1224 error: Option<DocumentError>,
1225}
1226
1227impl DidDocumentBuilder {
1228 #[must_use]
1230 pub fn context(mut self, context: Context) -> Self {
1231 self.document.context = Some(context);
1232 self
1233 }
1234
1235 #[must_use]
1237 pub fn also_known_as(mut self, uri: Uri) -> Self {
1238 self.document.also_known_as.push(uri);
1239 self
1240 }
1241
1242 #[must_use]
1244 pub fn controller(mut self, did: Did) -> Self {
1245 self.document.controller = Some(match self.document.controller.take() {
1246 None => OneOrMany::One(did),
1247 Some(existing) => {
1248 let mut dids = existing.into_vec();
1249 dids.push(did);
1250 OneOrMany::Many(dids)
1251 }
1252 });
1253 self
1254 }
1255
1256 #[must_use]
1258 pub fn verification_method(
1259 mut self,
1260 method: VerificationMethod,
1261 relationships: impl IntoIterator<Item = VerificationRelationship>,
1262 ) -> Self {
1263 if self.error.is_none() {
1264 self.error = self
1265 .document
1266 .insert_verification_method(method, relationships)
1267 .err();
1268 }
1269 self
1270 }
1271
1272 #[must_use]
1274 pub fn embedded_method(
1275 mut self,
1276 relationship: VerificationRelationship,
1277 method: VerificationMethod,
1278 ) -> Self {
1279 if self.error.is_none() {
1280 if self.document.verification_method(&method.id).is_some() {
1281 self.error = Some(DocumentError::DuplicateVerificationMethod(method.id));
1282 } else {
1283 self.document
1284 .relationship_mut(relationship)
1285 .push(MethodRef::embedded(method));
1286 }
1287 }
1288 self
1289 }
1290
1291 #[must_use]
1293 pub fn service(mut self, service: Service) -> Self {
1294 if self.error.is_none() {
1295 self.error = self.document.insert_service(service).err();
1296 }
1297 self
1298 }
1299
1300 #[must_use]
1303 pub fn property(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
1304 let name = name.into();
1305 if DidDocument::CORE_PROPERTIES.contains(&name.as_str()) {
1306 if self.error.is_none() {
1307 self.error = Some(DocumentError::ReservedProperty(name));
1308 }
1309 } else {
1310 self.document.properties.insert(name, value.into());
1311 }
1312 self
1313 }
1314
1315 pub fn build(self) -> Result<DidDocument, DocumentError> {
1321 match self.error {
1322 Some(error) => Err(error),
1323 None => Ok(self.document),
1324 }
1325 }
1326}