Skip to main content

identity_kit/did/
document.rs

1//! The DID document data model (DID Core §5) and operations on it.
2
3use 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;
17
18/// Why a [`DidDocument`] operation was refused.
19#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
20#[non_exhaustive]
21pub enum DocumentError {
22    /// `@context` is not a string, a map or a non-empty array.
23    #[error("`@context` must be a string, a map or a non-empty array")]
24    InvalidContext,
25    /// A verification method with this id is already in the document, or the document defines
26    /// the id twice with different material.
27    #[error("verification method `{0}` already exists")]
28    DuplicateVerificationMethod(DidUrl),
29    /// A service with this id is already in the document.
30    #[error("service `{0}` already exists")]
31    DuplicateService(DidUrl),
32    /// No verification method with this id is in the document.
33    #[error("verification method `{0}` not found")]
34    VerificationMethodNotFound(DidUrl),
35    /// The DID URL belongs to another DID than the document.
36    #[error("`{url}` does not belong to document `{document}`")]
37    ForeignDid {
38        /// The DID URL that was looked up.
39        url: DidUrl,
40        /// The `id` of the document.
41        document: Did,
42    },
43    /// The verification method exists but is not listed under the relationship.
44    #[error("verification method `{id}` is not listed under `{relationship}`")]
45    NotInRelationship {
46        /// The id of the verification method.
47        id: DidUrl,
48        /// The relationship that was required.
49        relationship: VerificationRelationship,
50    },
51    /// Not the name of a verification relationship.
52    #[error("unknown verification relationship `{0}`")]
53    UnknownRelationship(String),
54    /// An extension property with the name of a core property.
55    #[error("`{0}` is a core property, not an extension property")]
56    ReservedProperty(String),
57}
58
59// ---------------------------------------------------------------------------------------------
60// Building blocks
61// ---------------------------------------------------------------------------------------------
62
63/// A value that is either one `T` or a list of them, serialized without the list when single.
64///
65/// DID Core uses this for `controller` and `type` of a service.
66#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
67#[serde(untagged)]
68pub enum OneOrMany<T> {
69    /// A single value.
70    One(T),
71    /// A list of values, kept as a list even when it holds one.
72    Many(Vec<T>),
73}
74
75impl<T> OneOrMany<T> {
76    /// The values, in order.
77    pub fn iter(&self) -> impl Iterator<Item = &T> {
78        match self {
79            Self::One(one) => core::slice::from_ref(one).iter(),
80            Self::Many(many) => many.iter(),
81        }
82    }
83
84    /// The values, mutably.
85    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
86        match self {
87            Self::One(one) => core::slice::from_mut(one).iter_mut(),
88            Self::Many(many) => many.iter_mut(),
89        }
90    }
91
92    /// The number of values.
93    pub fn len(&self) -> usize {
94        match self {
95            Self::One(_) => 1,
96            Self::Many(many) => many.len(),
97        }
98    }
99
100    /// Whether there are no values (an empty list).
101    pub fn is_empty(&self) -> bool {
102        self.len() == 0
103    }
104
105    /// The first value, if any.
106    pub fn first(&self) -> Option<&T> {
107        self.iter().next()
108    }
109
110    /// Whether `value` is among the values.
111    pub fn contains(&self, value: &T) -> bool
112    where
113        T: PartialEq,
114    {
115        self.iter().any(|v| v == value)
116    }
117
118    /// The values as a `Vec`.
119    pub fn into_vec(self) -> Vec<T> {
120        match self {
121            Self::One(one) => vec![one],
122            Self::Many(many) => many,
123        }
124    }
125}
126
127/// `skip_serializing_if` for optional lists: `None` and empty lists are omitted alike.
128fn is_none_or_empty<T>(value: &Option<OneOrMany<T>>) -> bool {
129    value.as_ref().is_none_or(OneOrMany::is_empty)
130}
131
132impl<T> From<T> for OneOrMany<T> {
133    fn from(value: T) -> Self {
134        Self::One(value)
135    }
136}
137
138impl<T> From<Vec<T>> for OneOrMany<T> {
139    fn from(values: Vec<T>) -> Self {
140        Self::Many(values)
141    }
142}
143
144/// The `@context` of a DID document, carried verbatim: a string, a map or a non-empty array of
145/// them.
146///
147/// This crate does no JSON-LD processing; the context is data that round-trips.
148///
149/// # Examples
150///
151/// ```
152/// use identity_kit::did::Context;
153///
154/// let context = Context::uris([Context::DID_V1, "https://w3id.org/security/suites/jws-2020/v1"]);
155/// assert!(context.contains(Context::DID_V1));
156/// assert_eq!(
157///     serde_json::to_string(&context)?,
158///     r#"["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"]"#
159/// );
160/// # Ok::<(), serde_json::Error>(())
161/// ```
162#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
163#[serde(transparent)]
164pub struct Context(Value);
165
166impl Context {
167    /// The DID Core 1.0 context URI.
168    pub const DID_V1: &'static str = "https://www.w3.org/ns/did/v1";
169
170    /// The context `"https://www.w3.org/ns/did/v1"`.
171    pub fn did_v1() -> Self {
172        Self::uri(Self::DID_V1)
173    }
174
175    /// A single context URI.
176    pub fn uri(uri: impl Into<String>) -> Self {
177        Self(Value::String(uri.into()))
178    }
179
180    /// An array of context URIs.
181    pub fn uris<I, S>(uris: I) -> Self
182    where
183        I: IntoIterator<Item = S>,
184        S: Into<String>,
185    {
186        Self(Value::Array(
187            uris.into_iter().map(|s| Value::String(s.into())).collect(),
188        ))
189    }
190
191    /// Any JSON value allowed as a context.
192    ///
193    /// # Errors
194    ///
195    /// [`DocumentError::InvalidContext`] unless `value` is a string, a map or a non-empty array.
196    pub fn new(value: Value) -> Result<Self, DocumentError> {
197        match &value {
198            Value::String(_) | Value::Object(_) => Ok(Self(value)),
199            Value::Array(items) if !items.is_empty() => Ok(Self(value)),
200            _ => Err(DocumentError::InvalidContext),
201        }
202    }
203
204    /// The context as JSON.
205    pub fn as_value(&self) -> &Value {
206        &self.0
207    }
208
209    /// The context as JSON.
210    pub fn into_value(self) -> Value {
211        self.0
212    }
213
214    /// Whether `uri` is the context or one of the strings in the context array.
215    pub fn contains(&self, uri: &str) -> bool {
216        match &self.0 {
217            Value::String(s) => s == uri,
218            Value::Array(items) => items.iter().any(|item| item.as_str() == Some(uri)),
219            _ => false,
220        }
221    }
222}
223
224impl<'de> Deserialize<'de> for Context {
225    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
226        Self::new(Value::deserialize(deserializer)?).map_err(de::Error::custom)
227    }
228}
229
230/// A verification relationship (DID Core §5.3): the purpose a verification method may be used
231/// for. The `Display` and `FromStr` forms are the DID document property names.
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub enum VerificationRelationship {
235    /// `authentication`
236    Authentication,
237    /// `assertionMethod`
238    AssertionMethod,
239    /// `keyAgreement`
240    KeyAgreement,
241    /// `capabilityInvocation`
242    CapabilityInvocation,
243    /// `capabilityDelegation`
244    CapabilityDelegation,
245}
246
247impl VerificationRelationship {
248    /// Every relationship, in the order DID Core lists them.
249    pub const ALL: &'static [VerificationRelationship] = &[
250        Self::Authentication,
251        Self::AssertionMethod,
252        Self::KeyAgreement,
253        Self::CapabilityInvocation,
254        Self::CapabilityDelegation,
255    ];
256
257    /// The DID document property name, for example `assertionMethod`.
258    pub const fn as_str(self) -> &'static str {
259        match self {
260            Self::Authentication => "authentication",
261            Self::AssertionMethod => "assertionMethod",
262            Self::KeyAgreement => "keyAgreement",
263            Self::CapabilityInvocation => "capabilityInvocation",
264            Self::CapabilityDelegation => "capabilityDelegation",
265        }
266    }
267}
268
269impl fmt::Display for VerificationRelationship {
270    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271        f.write_str(self.as_str())
272    }
273}
274
275impl FromStr for VerificationRelationship {
276    type Err = DocumentError;
277
278    fn from_str(s: &str) -> Result<Self, Self::Err> {
279        Self::ALL
280            .iter()
281            .copied()
282            .find(|rel| rel.as_str() == s)
283            .ok_or_else(|| DocumentError::UnknownRelationship(s.to_owned()))
284    }
285}
286
287/// The `type` of a verification method: an open string with constants for the types this crate
288/// produces.
289///
290/// # Examples
291///
292/// ```
293/// use identity_kit::did::MethodType;
294///
295/// assert_eq!(MethodType::JSON_WEB_KEY_2020.as_str(), "JsonWebKey2020");
296/// assert_eq!(MethodType::new("JsonWebKey2020"), MethodType::JSON_WEB_KEY_2020);
297/// assert_eq!(serde_json::to_string(&MethodType::MULTIKEY)?, "\"Multikey\"");
298/// # Ok::<(), serde_json::Error>(())
299/// ```
300#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
301pub struct MethodType(Cow<'static, str>);
302
303impl MethodType {
304    /// `JsonWebKey2020`: `publicKeyJwk` material (JSON Web Signature 2020 suite).
305    pub const JSON_WEB_KEY_2020: MethodType = MethodType(Cow::Borrowed("JsonWebKey2020"));
306    /// `JsonWebKey`: `publicKeyJwk` material (Controlled Identifiers 1.0).
307    pub const JSON_WEB_KEY: MethodType = MethodType(Cow::Borrowed("JsonWebKey"));
308    /// `Multikey`: `publicKeyMultibase` material (Controlled Identifiers 1.0).
309    pub const MULTIKEY: MethodType = MethodType(Cow::Borrowed("Multikey"));
310    /// `Ed25519VerificationKey2020`: `publicKeyMultibase` material (Ed25519 Signature 2020 suite).
311    pub const ED25519_VERIFICATION_KEY_2020: MethodType =
312        MethodType(Cow::Borrowed("Ed25519VerificationKey2020"));
313
314    /// Any type name.
315    pub fn new(name: impl Into<String>) -> Self {
316        Self(Cow::Owned(name.into()))
317    }
318
319    /// The type name.
320    pub fn as_str(&self) -> &str {
321        &self.0
322    }
323}
324
325impl fmt::Debug for MethodType {
326    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327        fmt::Debug::fmt(self.as_str(), f)
328    }
329}
330
331impl fmt::Display for MethodType {
332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333        f.write_str(self.as_str())
334    }
335}
336
337impl From<&str> for MethodType {
338    fn from(name: &str) -> Self {
339        Self::new(name)
340    }
341}
342
343impl From<String> for MethodType {
344    fn from(name: String) -> Self {
345        Self::new(name)
346    }
347}
348
349impl PartialEq<str> for MethodType {
350    fn eq(&self, other: &str) -> bool {
351        self.as_str() == other
352    }
353}
354
355impl PartialEq<&str> for MethodType {
356    fn eq(&self, other: &&str) -> bool {
357        self.as_str() == *other
358    }
359}
360
361impl Serialize for MethodType {
362    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
363        serializer.serialize_str(self.as_str())
364    }
365}
366
367impl<'de> Deserialize<'de> for MethodType {
368    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
369        String::deserialize(deserializer).map(Self::new)
370    }
371}
372
373// ---------------------------------------------------------------------------------------------
374// Verification methods
375// ---------------------------------------------------------------------------------------------
376
377/// The verification material of a verification method (DID Core §5.2.1): exactly one of
378/// `publicKeyJwk` and `publicKeyMultibase`.
379///
380/// A `publicKeyJwk` must not carry private parameters; such a key is rejected when read and
381/// refused when written.
382#[derive(Debug, Clone, PartialEq, Eq)]
383#[non_exhaustive]
384pub enum VerificationMaterial {
385    /// `publicKeyJwk`: a public JSON Web Key.
386    PublicKeyJwk(Box<Jwk>),
387    /// `publicKeyMultibase`: a multibase-encoded public key.
388    PublicKeyMultibase(String),
389}
390
391impl VerificationMaterial {
392    /// `publicKeyJwk` with the public part of `jwk`.
393    pub fn jwk(jwk: &Jwk) -> Self {
394        Self::PublicKeyJwk(Box::new(jwk.public()))
395    }
396
397    /// `publicKeyMultibase`.
398    pub fn multibase(value: impl Into<String>) -> Self {
399        Self::PublicKeyMultibase(value.into())
400    }
401
402    /// The JWK, when the material is `publicKeyJwk`.
403    pub fn as_jwk(&self) -> Option<&Jwk> {
404        match self {
405            Self::PublicKeyJwk(jwk) => Some(jwk),
406            Self::PublicKeyMultibase(_) => None,
407        }
408    }
409
410    /// The multibase string, when the material is `publicKeyMultibase`.
411    pub fn as_multibase(&self) -> Option<&str> {
412        match self {
413            Self::PublicKeyMultibase(value) => Some(value),
414            Self::PublicKeyJwk(_) => None,
415        }
416    }
417}
418
419impl Serialize for VerificationMaterial {
420    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
421        let mut map = serializer.serialize_map(Some(1))?;
422        match self {
423            Self::PublicKeyJwk(jwk) => {
424                if jwk.is_private() {
425                    return Err(serde::ser::Error::custom(
426                        "`publicKeyJwk` must not contain private parameters",
427                    ));
428                }
429                map.serialize_entry("publicKeyJwk", jwk)?;
430            }
431            Self::PublicKeyMultibase(value) => map.serialize_entry("publicKeyMultibase", value)?,
432        }
433        map.end()
434    }
435}
436
437/// The two material members as optional fields, so they can be flattened out of a method.
438#[derive(Deserialize)]
439struct MaterialMembers {
440    #[serde(rename = "publicKeyJwk", default)]
441    public_key_jwk: Option<Jwk>,
442    #[serde(rename = "publicKeyMultibase", default)]
443    public_key_multibase: Option<String>,
444}
445
446impl<'de> Deserialize<'de> for VerificationMaterial {
447    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
448        let members = MaterialMembers::deserialize(deserializer)?;
449        match (members.public_key_jwk, members.public_key_multibase) {
450            (Some(jwk), None) if jwk.is_private() => Err(de::Error::custom(
451                "`publicKeyJwk` must not contain private parameters",
452            )),
453            (Some(jwk), None) => Ok(Self::PublicKeyJwk(Box::new(jwk))),
454            (None, Some(value)) => Ok(Self::PublicKeyMultibase(value)),
455            (None, None) => Err(de::Error::custom(
456                "verification method has neither `publicKeyJwk` nor `publicKeyMultibase`",
457            )),
458            (Some(_), Some(_)) => Err(de::Error::custom(
459                "verification method has both `publicKeyJwk` and `publicKeyMultibase`",
460            )),
461        }
462    }
463}
464
465/// A verification method (DID Core §5.2): a public key with an id, a type and a controller.
466///
467/// Members other than the four core ones live in `properties`, in insertion order.
468///
469/// # Examples
470///
471/// ```
472/// use identity_kit::did::{MethodType, VerificationMaterial, VerificationMethod};
473///
474/// let json = r#"{
475///   "id": "did:example:123#key-1",
476///   "type": "Multikey",
477///   "controller": "did:example:123",
478///   "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
479/// }"#;
480/// let method: VerificationMethod = serde_json::from_str(json)?;
481/// assert_eq!(method.method_type, MethodType::MULTIKEY);
482/// assert_eq!(method.controller.as_str(), "did:example:123");
483/// assert_eq!(
484///     method.material.as_multibase(),
485///     Some("z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu")
486/// );
487/// # Ok::<(), serde_json::Error>(())
488/// ```
489#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
490#[non_exhaustive]
491pub struct VerificationMethod {
492    /// The DID URL identifying the method, usually the document DID with a fragment.
493    pub id: DidUrl,
494    /// The `type`, which tells which cryptographic suite reads the material.
495    #[serde(rename = "type")]
496    pub method_type: MethodType,
497    /// The DID of the controller of the key.
498    pub controller: Did,
499    /// `publicKeyJwk` or `publicKeyMultibase`.
500    #[serde(flatten)]
501    pub material: VerificationMaterial,
502    /// Every other member, in insertion order.
503    #[serde(flatten)]
504    pub properties: IndexMap<String, Value>,
505}
506
507impl VerificationMethod {
508    /// A verification method with the four core members.
509    pub fn new(
510        id: DidUrl,
511        method_type: MethodType,
512        controller: Did,
513        material: VerificationMaterial,
514    ) -> Self {
515        Self {
516            id,
517            method_type,
518            controller,
519            material,
520            properties: IndexMap::new(),
521        }
522    }
523
524    /// The `publicKeyJwk`, if that is the material.
525    pub fn public_key_jwk(&self) -> Option<&Jwk> {
526        self.material.as_jwk()
527    }
528
529    /// The `publicKeyMultibase`, if that is the material.
530    pub fn public_key_multibase(&self) -> Option<&str> {
531        self.material.as_multibase()
532    }
533}
534
535/// An entry of a verification relationship: a reference to a method in `verificationMethod`,
536/// or a method embedded in the relationship and usable for that purpose only (DID Core §5.3).
537#[derive(Debug, Clone, PartialEq, Eq)]
538pub enum MethodRef {
539    /// A DID URL (possibly relative) of a method listed under `verificationMethod`.
540    Reference(DidUrlReference),
541    /// A method defined in place.
542    Embedded(Box<VerificationMethod>),
543}
544
545impl MethodRef {
546    /// A reference to `id`.
547    pub fn reference(id: impl Into<DidUrlReference>) -> Self {
548        Self::Reference(id.into())
549    }
550
551    /// An embedded method.
552    pub fn embedded(method: VerificationMethod) -> Self {
553        Self::Embedded(Box::new(method))
554    }
555
556    /// The embedded method, if this entry embeds one.
557    pub fn as_embedded(&self) -> Option<&VerificationMethod> {
558        match self {
559            Self::Embedded(method) => Some(method),
560            Self::Reference(_) => None,
561        }
562    }
563
564    /// The reference, if this entry is one.
565    pub fn as_reference(&self) -> Option<&DidUrlReference> {
566        match self {
567            Self::Reference(reference) => Some(reference),
568            Self::Embedded(_) => None,
569        }
570    }
571
572    /// Whether this entry denotes the method `id` in a document whose `id` is `base`.
573    pub fn refers_to(&self, id: &DidUrl, base: &Did) -> bool {
574        match self {
575            Self::Reference(reference) => reference.refers_to(id, base),
576            Self::Embedded(method) => method.id == *id,
577        }
578    }
579}
580
581impl From<DidUrl> for MethodRef {
582    fn from(id: DidUrl) -> Self {
583        Self::Reference(id.into())
584    }
585}
586
587impl From<DidUrlReference> for MethodRef {
588    fn from(reference: DidUrlReference) -> Self {
589        Self::Reference(reference)
590    }
591}
592
593impl From<VerificationMethod> for MethodRef {
594    fn from(method: VerificationMethod) -> Self {
595        Self::embedded(method)
596    }
597}
598
599impl Serialize for MethodRef {
600    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
601        match self {
602            Self::Reference(reference) => reference.serialize(serializer),
603            Self::Embedded(method) => method.serialize(serializer),
604        }
605    }
606}
607
608impl<'de> Deserialize<'de> for MethodRef {
609    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
610        struct MethodRefVisitor;
611
612        impl<'de> Visitor<'de> for MethodRefVisitor {
613            type Value = MethodRef;
614
615            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616                f.write_str("a DID URL string or a verification method object")
617            }
618
619            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
620                DidUrlReference::parse(value)
621                    .map(MethodRef::Reference)
622                    .map_err(E::custom)
623            }
624
625            fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
626                VerificationMethod::deserialize(de::value::MapAccessDeserializer::new(map))
627                    .map(MethodRef::embedded)
628            }
629        }
630
631        deserializer.deserialize_any(MethodRefVisitor)
632    }
633}
634
635// ---------------------------------------------------------------------------------------------
636// Services
637// ---------------------------------------------------------------------------------------------
638
639/// The `serviceEndpoint` of a service (DID Core §5.4): a URI, a set of URIs, or a map.
640#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
641#[serde(untagged)]
642pub enum ServiceEndpoint {
643    /// A single URI.
644    Uri(Uri),
645    /// A non-empty set of URIs, in document order.
646    Set(IndexSet<Uri>),
647    /// A map, carried verbatim.
648    Map(IndexMap<String, Value>),
649}
650
651impl ServiceEndpoint {
652    /// A single URI.
653    pub fn uri(uri: Uri) -> Self {
654        Self::Uri(uri)
655    }
656
657    /// The URIs, when the endpoint is a URI or a set of them.
658    pub fn uris(&self) -> impl Iterator<Item = &Uri> {
659        let slice: Box<dyn Iterator<Item = &Uri>> = match self {
660            Self::Uri(uri) => Box::new(core::iter::once(uri)),
661            Self::Set(set) => Box::new(set.iter()),
662            Self::Map(_) => Box::new(core::iter::empty()),
663        };
664        slice
665    }
666}
667
668impl From<Uri> for ServiceEndpoint {
669    fn from(uri: Uri) -> Self {
670        Self::Uri(uri)
671    }
672}
673
674impl<'de> Deserialize<'de> for ServiceEndpoint {
675    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
676        struct EndpointVisitor;
677
678        impl<'de> Visitor<'de> for EndpointVisitor {
679            type Value = ServiceEndpoint;
680
681            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
682                f.write_str("a URI string, a non-empty array of URI strings, or an object")
683            }
684
685            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
686                Uri::parse(value)
687                    .map(ServiceEndpoint::Uri)
688                    .map_err(E::custom)
689            }
690
691            fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
692                let mut set = IndexSet::new();
693                while let Some(uri) = seq.next_element::<Uri>()? {
694                    set.insert(uri);
695                }
696                if set.is_empty() {
697                    return Err(de::Error::custom(
698                        "`serviceEndpoint` set must contain at least one URI",
699                    ));
700                }
701                Ok(ServiceEndpoint::Set(set))
702            }
703
704            fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
705                let mut entries = IndexMap::new();
706                while let Some((key, value)) = map.next_entry::<String, Value>()? {
707                    entries.insert(key, value);
708                }
709                Ok(ServiceEndpoint::Map(entries))
710            }
711        }
712
713        deserializer.deserialize_any(EndpointVisitor)
714    }
715}
716
717/// A service (DID Core §5.4): a way of interacting with the DID subject.
718///
719/// `type` serializes as a string when single. Members other than the three core ones live in
720/// `properties`, in insertion order.
721#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
722#[non_exhaustive]
723pub struct Service {
724    /// The DID URL identifying the service, usually the document DID with a fragment.
725    pub id: DidUrl,
726    /// The service type or types.
727    #[serde(rename = "type")]
728    pub service_type: OneOrMany<String>,
729    /// Where the service is.
730    #[serde(rename = "serviceEndpoint")]
731    pub service_endpoint: ServiceEndpoint,
732    /// Every other member, in insertion order.
733    #[serde(flatten)]
734    pub properties: IndexMap<String, Value>,
735}
736
737impl Service {
738    /// A service with the three core members.
739    pub fn new(
740        id: DidUrl,
741        service_type: impl Into<OneOrMany<String>>,
742        service_endpoint: impl Into<ServiceEndpoint>,
743    ) -> Self {
744        Self {
745            id,
746            service_type: service_type.into(),
747            service_endpoint: service_endpoint.into(),
748            properties: IndexMap::new(),
749        }
750    }
751
752    /// Whether `service_type` is among the service's types.
753    pub fn has_type(&self, service_type: &str) -> bool {
754        self.service_type.iter().any(|t| t == service_type)
755    }
756}
757
758impl From<&str> for OneOrMany<String> {
759    fn from(value: &str) -> Self {
760        Self::One(value.to_owned())
761    }
762}
763
764// ---------------------------------------------------------------------------------------------
765// The document
766// ---------------------------------------------------------------------------------------------
767
768/// A DID document (DID Core §5): the core properties as fields, everything else in `properties`.
769///
770/// The JSON representation is deterministic: `@context` comes first, then `id`, the core
771/// properties in the order DID Core lists them, and extension properties in insertion order.
772/// `None` and empty lists are omitted. A document parsed from JSON and written again holds the
773/// same members with the same values; the bytes are identical when the input already used that
774/// order. Extension properties must not use a core property name (see
775/// [`CORE_PROPERTIES`](Self::CORE_PROPERTIES)); the builder refuses one, and a document whose
776/// `properties` field holds one serializes a duplicate member.
777///
778/// The fields are public for reading and plain mutation; the methods keep the invariants that
779/// DID Core requires (unique method and service ids, references that point at listed methods).
780/// Deserialization enforces them too: a document that defines one verification method id twice
781/// with different content (listed or embedded) is rejected, so no lookup can pick different
782/// material for one id, and so is one with two services sharing an id, as DID Core §5.4 requires
783/// of a consumer. Embedding the same method under several relationships, as DID Core's own
784/// examples do, is one definition and allowed.
785///
786/// # Examples
787///
788/// ```
789/// use identity_kit::did::{DidDocument, VerificationRelationship};
790///
791/// // DID Core §4.1, Example 1 (with its editorial typo fixed).
792/// let json = r#"{
793///   "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1"],
794///   "id": "did:example:123456789abcdefghi",
795///   "authentication": [{
796///     "id": "did:example:123456789abcdefghi#keys-1",
797///     "type": "Ed25519VerificationKey2020",
798///     "controller": "did:example:123456789abcdefghi",
799///     "publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
800///   }]
801/// }"#;
802/// let document: DidDocument = serde_json::from_str(json)?;
803/// assert_eq!(document.id.as_str(), "did:example:123456789abcdefghi");
804///
805/// let key = document.id.join("#keys-1")?;
806/// let method = document.resolve_verification_method(&key, Some(VerificationRelationship::Authentication))?;
807/// assert_eq!(method.public_key_multibase(), Some("zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"));
808///
809/// // The method is embedded under `authentication` and usable for nothing else.
810/// assert!(document.resolve_verification_method(&key, Some(VerificationRelationship::AssertionMethod)).is_err());
811/// # Ok::<(), Box<dyn std::error::Error>>(())
812/// ```
813#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
814#[non_exhaustive]
815#[serde(remote = "Self")]
816pub struct DidDocument {
817    /// `@context`, carried verbatim.
818    #[serde(rename = "@context", default, skip_serializing_if = "Option::is_none")]
819    pub context: Option<Context>,
820    /// The DID of the subject.
821    pub id: Did,
822    /// Other identifiers of the subject.
823    #[serde(rename = "alsoKnownAs", default, skip_serializing_if = "Vec::is_empty")]
824    pub also_known_as: Vec<Uri>,
825    /// The DIDs whose controllers may change this document; omitted when `None` or empty, and
826    /// `None` when read as an empty set.
827    #[serde(default, skip_serializing_if = "is_none_or_empty")]
828    pub controller: Option<OneOrMany<Did>>,
829    /// Verification methods that relationships may reference.
830    #[serde(
831        rename = "verificationMethod",
832        default,
833        skip_serializing_if = "Vec::is_empty"
834    )]
835    pub verification_method: Vec<VerificationMethod>,
836    /// `authentication`
837    #[serde(default, skip_serializing_if = "Vec::is_empty")]
838    pub authentication: Vec<MethodRef>,
839    /// `assertionMethod`
840    #[serde(
841        rename = "assertionMethod",
842        default,
843        skip_serializing_if = "Vec::is_empty"
844    )]
845    pub assertion_method: Vec<MethodRef>,
846    /// `keyAgreement`
847    #[serde(
848        rename = "keyAgreement",
849        default,
850        skip_serializing_if = "Vec::is_empty"
851    )]
852    pub key_agreement: Vec<MethodRef>,
853    /// `capabilityInvocation`
854    #[serde(
855        rename = "capabilityInvocation",
856        default,
857        skip_serializing_if = "Vec::is_empty"
858    )]
859    pub capability_invocation: Vec<MethodRef>,
860    /// `capabilityDelegation`
861    #[serde(
862        rename = "capabilityDelegation",
863        default,
864        skip_serializing_if = "Vec::is_empty"
865    )]
866    pub capability_delegation: Vec<MethodRef>,
867    /// Services.
868    #[serde(default, skip_serializing_if = "Vec::is_empty")]
869    pub service: Vec<Service>,
870    /// Every other property, in insertion order.
871    #[serde(flatten)]
872    pub properties: IndexMap<String, Value>,
873}
874
875impl Serialize for DidDocument {
876    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
877        Self::serialize(self, serializer)
878    }
879}
880
881impl<'de> Deserialize<'de> for DidDocument {
882    /// Reads the document and rejects duplicate verification method or service ids. An empty
883    /// `controller` set reads as no controller, which is how it is written.
884    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
885        let mut document = Self::deserialize(deserializer)?;
886        document.check_unique_ids().map_err(de::Error::custom)?;
887        if is_none_or_empty(&document.controller) {
888            document.controller = None;
889        }
890        Ok(document)
891    }
892}
893
894impl DidDocument {
895    /// The property names DID Core §5 defines, which `properties` must not contain.
896    pub const CORE_PROPERTIES: &'static [&'static str] = &[
897        "@context",
898        "id",
899        "alsoKnownAs",
900        "controller",
901        "verificationMethod",
902        "authentication",
903        "assertionMethod",
904        "keyAgreement",
905        "capabilityInvocation",
906        "capabilityDelegation",
907        "service",
908    ];
909
910    /// An empty document for `id`.
911    pub fn new(id: Did) -> Self {
912        Self {
913            context: None,
914            id,
915            also_known_as: Vec::new(),
916            controller: None,
917            verification_method: Vec::new(),
918            authentication: Vec::new(),
919            assertion_method: Vec::new(),
920            key_agreement: Vec::new(),
921            capability_invocation: Vec::new(),
922            capability_delegation: Vec::new(),
923            service: Vec::new(),
924            properties: IndexMap::new(),
925        }
926    }
927
928    /// A builder for a document for `id`.
929    pub fn builder(id: Did) -> DidDocumentBuilder {
930        DidDocumentBuilder {
931            document: Self::new(id),
932            error: None,
933        }
934    }
935
936    /// The entries of `relationship`.
937    pub fn relationship(&self, relationship: VerificationRelationship) -> &[MethodRef] {
938        match relationship {
939            VerificationRelationship::Authentication => &self.authentication,
940            VerificationRelationship::AssertionMethod => &self.assertion_method,
941            VerificationRelationship::KeyAgreement => &self.key_agreement,
942            VerificationRelationship::CapabilityInvocation => &self.capability_invocation,
943            VerificationRelationship::CapabilityDelegation => &self.capability_delegation,
944        }
945    }
946
947    /// The entries of `relationship`, mutably.
948    pub fn relationship_mut(
949        &mut self,
950        relationship: VerificationRelationship,
951    ) -> &mut Vec<MethodRef> {
952        match relationship {
953            VerificationRelationship::Authentication => &mut self.authentication,
954            VerificationRelationship::AssertionMethod => &mut self.assertion_method,
955            VerificationRelationship::KeyAgreement => &mut self.key_agreement,
956            VerificationRelationship::CapabilityInvocation => &mut self.capability_invocation,
957            VerificationRelationship::CapabilityDelegation => &mut self.capability_delegation,
958        }
959    }
960
961    /// The methods embedded in any relationship.
962    fn embedded_methods(&self) -> impl Iterator<Item = &VerificationMethod> {
963        VerificationRelationship::ALL
964            .iter()
965            .flat_map(|rel| self.relationship(*rel))
966            .filter_map(MethodRef::as_embedded)
967    }
968
969    /// The verification method with `id`, listed under `verificationMethod` or embedded in a
970    /// relationship.
971    pub fn verification_method(&self, id: &DidUrl) -> Option<&VerificationMethod> {
972        self.verification_method
973            .iter()
974            .chain(self.embedded_methods())
975            .find(|method| method.id == *id)
976    }
977
978    /// The verification methods usable for `relationship`, or every method in the document
979    /// when `relationship` is `None`.
980    ///
981    /// References are followed; a reference to a method that is not listed under
982    /// `verificationMethod` yields nothing.
983    pub fn methods(
984        &self,
985        relationship: Option<VerificationRelationship>,
986    ) -> impl Iterator<Item = &VerificationMethod> {
987        let entries: Box<dyn Iterator<Item = &VerificationMethod>> =
988            match relationship {
989                None => Box::new(
990                    self.verification_method
991                        .iter()
992                        .chain(self.embedded_methods()),
993                ),
994                Some(rel) => Box::new(self.relationship(rel).iter().filter_map(
995                    |entry| match entry {
996                        MethodRef::Embedded(method) => Some(&**method),
997                        MethodRef::Reference(reference) => {
998                            let id = reference.resolve(&self.id).ok()?;
999                            self.verification_method.iter().find(|m| m.id == id)
1000                        }
1001                    },
1002                )),
1003            };
1004        entries
1005    }
1006
1007    /// The verification method `id`, optionally restricted to those usable for `relationship`.
1008    ///
1009    /// `id` must belong to this document's DID. The method may be listed under
1010    /// `verificationMethod` or embedded in a relationship; with a `relationship`, it must be
1011    /// referenced (absolutely or relatively) or embedded under that relationship.
1012    ///
1013    /// # Errors
1014    ///
1015    /// - [`DocumentError::ForeignDid`] when `id` is a DID URL of another DID.
1016    /// - [`DocumentError::VerificationMethodNotFound`] when no method has that id.
1017    /// - [`DocumentError::NotInRelationship`] when it exists but not under `relationship`.
1018    pub fn resolve_verification_method(
1019        &self,
1020        id: &DidUrl,
1021        relationship: Option<VerificationRelationship>,
1022    ) -> Result<&VerificationMethod, DocumentError> {
1023        if id.did() != &self.id {
1024            return Err(DocumentError::ForeignDid {
1025                url: id.clone(),
1026                document: self.id.clone(),
1027            });
1028        }
1029        let Some(relationship) = relationship else {
1030            return self
1031                .verification_method(id)
1032                .ok_or_else(|| DocumentError::VerificationMethodNotFound(id.clone()));
1033        };
1034        for entry in self.relationship(relationship) {
1035            match entry {
1036                MethodRef::Embedded(method) if method.id == *id => return Ok(method),
1037                MethodRef::Reference(reference) if reference.refers_to(id, &self.id) => {
1038                    return self
1039                        .verification_method
1040                        .iter()
1041                        .find(|method| method.id == *id)
1042                        .ok_or_else(|| DocumentError::VerificationMethodNotFound(id.clone()));
1043                }
1044                _ => {}
1045            }
1046        }
1047        if self.verification_method(id).is_some() {
1048            Err(DocumentError::NotInRelationship {
1049                id: id.clone(),
1050                relationship,
1051            })
1052        } else {
1053            Err(DocumentError::VerificationMethodNotFound(id.clone()))
1054        }
1055    }
1056
1057    /// [`resolve_verification_method`](Self::resolve_verification_method) for a reference that
1058    /// may be relative (`#key-1`), resolved against this document's `id`.
1059    ///
1060    /// # Errors
1061    ///
1062    /// As [`resolve_verification_method`](Self::resolve_verification_method).
1063    pub fn resolve_method_reference(
1064        &self,
1065        reference: &DidUrlReference,
1066        relationship: Option<VerificationRelationship>,
1067    ) -> Result<&VerificationMethod, DocumentError> {
1068        // A relative reference this type accepted always joins to a DID.
1069        let id = reference.resolve(&self.id).map_err(|_| match reference {
1070            DidUrlReference::Absolute(url) => DocumentError::ForeignDid {
1071                url: url.clone(),
1072                document: self.id.clone(),
1073            },
1074            DidUrlReference::Relative(_) => {
1075                DocumentError::VerificationMethodNotFound(self.id.to_url())
1076            }
1077        })?;
1078        self.resolve_verification_method(&id, relationship)
1079    }
1080
1081    /// Adds `method` under `verificationMethod` and references it from each of `relationships`.
1082    ///
1083    /// # Errors
1084    ///
1085    /// [`DocumentError::DuplicateVerificationMethod`] when a method with that id exists, listed
1086    /// or embedded; the document is unchanged.
1087    pub fn insert_verification_method(
1088        &mut self,
1089        method: VerificationMethod,
1090        relationships: impl IntoIterator<Item = VerificationRelationship>,
1091    ) -> Result<(), DocumentError> {
1092        if self.verification_method(&method.id).is_some() {
1093            return Err(DocumentError::DuplicateVerificationMethod(method.id));
1094        }
1095        let id = method.id.clone();
1096        self.verification_method.push(method);
1097        for relationship in relationships {
1098            self.attach_relationship(&id, relationship)?;
1099        }
1100        Ok(())
1101    }
1102
1103    /// Checks that every verification method id (listed or embedded) has one definition and that
1104    /// no two services share an id: the invariant the mutating methods keep and deserialization
1105    /// enforces. The same method embedded under several relationships is one definition.
1106    ///
1107    /// # Errors
1108    ///
1109    /// [`DocumentError::DuplicateVerificationMethod`] naming the first id defined twice with
1110    /// different content, or [`DocumentError::DuplicateService`] naming the first repeated
1111    /// service id.
1112    pub fn check_unique_ids(&self) -> Result<(), DocumentError> {
1113        let mut seen = HashMap::new();
1114        for method in self
1115            .verification_method
1116            .iter()
1117            .chain(self.embedded_methods())
1118        {
1119            if *seen.entry(&method.id).or_insert(method) != method {
1120                return Err(DocumentError::DuplicateVerificationMethod(
1121                    method.id.clone(),
1122                ));
1123            }
1124        }
1125        let mut seen = HashSet::new();
1126        for service in &self.service {
1127            if !seen.insert(&service.id) {
1128                return Err(DocumentError::DuplicateService(service.id.clone()));
1129            }
1130        }
1131        Ok(())
1132    }
1133
1134    /// Removes the method `id`, listed or embedded, and every relationship entry for it.
1135    pub fn remove_verification_method(&mut self, id: &DidUrl) -> Option<VerificationMethod> {
1136        // Every listed entry with the id goes, should plain mutation have duplicated it.
1137        let (matching, rest): (Vec<_>, Vec<_>) = mem::take(&mut self.verification_method)
1138            .into_iter()
1139            .partition(|method| method.id == *id);
1140        self.verification_method = rest;
1141        let listed = matching.into_iter().next();
1142        let mut embedded = None;
1143        let base = self.id.clone();
1144        for relationship in VerificationRelationship::ALL {
1145            let entries = self.relationship_mut(*relationship);
1146            let mut index = 0;
1147            while index < entries.len() {
1148                if entries[index].refers_to(id, &base) {
1149                    if let MethodRef::Embedded(method) = entries.remove(index) {
1150                        embedded.get_or_insert(*method);
1151                    }
1152                } else {
1153                    index += 1;
1154                }
1155            }
1156        }
1157        listed.or(embedded)
1158    }
1159
1160    /// References the listed method `id` from `relationship`.
1161    ///
1162    /// Returns whether an entry was added: `Ok(false)` when the relationship already references
1163    /// or embeds the method.
1164    ///
1165    /// # Errors
1166    ///
1167    /// [`DocumentError::VerificationMethodNotFound`] when `id` is not listed under
1168    /// `verificationMethod` (a reference to an embedded method would dangle).
1169    pub fn attach_relationship(
1170        &mut self,
1171        id: &DidUrl,
1172        relationship: VerificationRelationship,
1173    ) -> Result<bool, DocumentError> {
1174        if !self.verification_method.iter().any(|m| m.id == *id) {
1175            return Err(DocumentError::VerificationMethodNotFound(id.clone()));
1176        }
1177        let base = self.id.clone();
1178        let entries = self.relationship_mut(relationship);
1179        if entries.iter().any(|entry| entry.refers_to(id, &base)) {
1180            return Ok(false);
1181        }
1182        entries.push(MethodRef::Reference(id.clone().into()));
1183        Ok(true)
1184    }
1185
1186    /// Removes every entry for the method `id` from `relationship`, returning whether there
1187    /// was one.
1188    pub fn detach_relationship(
1189        &mut self,
1190        id: &DidUrl,
1191        relationship: VerificationRelationship,
1192    ) -> bool {
1193        let base = self.id.clone();
1194        let entries = self.relationship_mut(relationship);
1195        let before = entries.len();
1196        entries.retain(|entry| !entry.refers_to(id, &base));
1197        entries.len() != before
1198    }
1199
1200    /// The service `id`.
1201    pub fn service(&self, id: &DidUrl) -> Option<&Service> {
1202        self.service.iter().find(|service| service.id == *id)
1203    }
1204
1205    /// Adds `service`.
1206    ///
1207    /// # Errors
1208    ///
1209    /// [`DocumentError::DuplicateService`] when a service with that id exists.
1210    pub fn insert_service(&mut self, service: Service) -> Result<(), DocumentError> {
1211        if self.service(&service.id).is_some() {
1212            return Err(DocumentError::DuplicateService(service.id));
1213        }
1214        self.service.push(service);
1215        Ok(())
1216    }
1217
1218    /// Removes the service `id`.
1219    pub fn remove_service(&mut self, id: &DidUrl) -> Option<Service> {
1220        self.service
1221            .iter()
1222            .position(|service| service.id == *id)
1223            .map(|index| self.service.remove(index))
1224    }
1225
1226    /// Rewrites every DID in the document through `f`: the `id`, the controllers, the ids and
1227    /// controllers of verification methods (listed and embedded), absolute relationship
1228    /// references and service ids. Relative references, `alsoKnownAs` and extension properties
1229    /// are left as they are.
1230    ///
1231    /// This is how a method whose DID depends on the document (a `did:web` moving domains, a
1232    /// placeholder DID replaced by the registered one) produces its final document.
1233    ///
1234    /// `f` is expected to map distinct DIDs to distinct DIDs. Merging two DIDs into one can give
1235    /// two methods or services the same id; that is not checked here, and
1236    /// [`check_unique_ids`](Self::check_unique_ids) reports it.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// use identity_kit::did::{Did, DidDocument, MethodType, VerificationMaterial, VerificationMethod, VerificationRelationship};
1242    ///
1243    /// let placeholder = Did::parse("did:example:placeholder")?;
1244    /// let mut document = DidDocument::new(placeholder.clone());
1245    /// document.insert_verification_method(
1246    ///     VerificationMethod::new(
1247    ///         placeholder.join("#key-1")?,
1248    ///         MethodType::MULTIKEY,
1249    ///         placeholder.clone(),
1250    ///         VerificationMaterial::multibase("z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"),
1251    ///     ),
1252    ///     [VerificationRelationship::Authentication],
1253    /// )?;
1254    ///
1255    /// let registered = Did::parse("did:web:example.com")?;
1256    /// document.map_dids(|did| if did == placeholder { registered.clone() } else { did });
1257    ///
1258    /// assert_eq!(document.id, registered);
1259    /// assert_eq!(document.verification_method[0].id.as_str(), "did:web:example.com#key-1");
1260    /// assert_eq!(document.verification_method[0].controller, registered);
1261    /// let key = registered.join("#key-1")?;
1262    /// assert!(document.resolve_verification_method(&key, Some(VerificationRelationship::Authentication)).is_ok());
1263    /// # Ok::<(), Box<dyn std::error::Error>>(())
1264    /// ```
1265    pub fn map_dids(&mut self, mut f: impl FnMut(Did) -> Did) {
1266        fn map_url(url: &mut DidUrl, f: &mut impl FnMut(Did) -> Did) {
1267            let did = f(url.did().clone());
1268            if &did != url.did() {
1269                *url = url.with_did(did);
1270            }
1271        }
1272        fn map_method(method: &mut VerificationMethod, f: &mut impl FnMut(Did) -> Did) {
1273            map_url(&mut method.id, f);
1274            method.controller = f(method.controller.clone());
1275        }
1276
1277        self.id = f(self.id.clone());
1278        if let Some(controller) = &mut self.controller {
1279            for did in controller.iter_mut() {
1280                *did = f(did.clone());
1281            }
1282        }
1283        for method in &mut self.verification_method {
1284            map_method(method, &mut f);
1285        }
1286        for relationship in VerificationRelationship::ALL {
1287            for entry in self.relationship_mut(*relationship) {
1288                match entry {
1289                    MethodRef::Reference(DidUrlReference::Absolute(url)) => map_url(url, &mut f),
1290                    MethodRef::Reference(DidUrlReference::Relative(_)) => {}
1291                    MethodRef::Embedded(method) => map_method(method, &mut f),
1292                }
1293            }
1294        }
1295        for service in &mut self.service {
1296            map_url(&mut service.id, &mut f);
1297        }
1298    }
1299}
1300
1301/// Builds a [`DidDocument`], reporting the first invariant violation at [`build`](Self::build).
1302#[derive(Debug, Clone)]
1303pub struct DidDocumentBuilder {
1304    document: DidDocument,
1305    error: Option<DocumentError>,
1306}
1307
1308impl DidDocumentBuilder {
1309    /// Sets `@context`.
1310    #[must_use]
1311    pub fn context(mut self, context: Context) -> Self {
1312        self.document.context = Some(context);
1313        self
1314    }
1315
1316    /// Adds an `alsoKnownAs` URI.
1317    #[must_use]
1318    pub fn also_known_as(mut self, uri: Uri) -> Self {
1319        self.document.also_known_as.push(uri);
1320        self
1321    }
1322
1323    /// Adds a controller; one controller serializes as a string, more as an array.
1324    #[must_use]
1325    pub fn controller(mut self, did: Did) -> Self {
1326        self.document.controller = Some(match self.document.controller.take() {
1327            None => OneOrMany::One(did),
1328            Some(existing) => {
1329                let mut dids = existing.into_vec();
1330                dids.push(did);
1331                OneOrMany::Many(dids)
1332            }
1333        });
1334        self
1335    }
1336
1337    /// Adds a verification method under `verificationMethod`, referenced from `relationships`.
1338    #[must_use]
1339    pub fn verification_method(
1340        mut self,
1341        method: VerificationMethod,
1342        relationships: impl IntoIterator<Item = VerificationRelationship>,
1343    ) -> Self {
1344        if self.error.is_none() {
1345            self.error = self
1346                .document
1347                .insert_verification_method(method, relationships)
1348                .err();
1349        }
1350        self
1351    }
1352
1353    /// Embeds a verification method in `relationship`, usable for that purpose only.
1354    #[must_use]
1355    pub fn embedded_method(
1356        mut self,
1357        relationship: VerificationRelationship,
1358        method: VerificationMethod,
1359    ) -> Self {
1360        if self.error.is_none() {
1361            if self.document.verification_method(&method.id).is_some() {
1362                self.error = Some(DocumentError::DuplicateVerificationMethod(method.id));
1363            } else {
1364                self.document
1365                    .relationship_mut(relationship)
1366                    .push(MethodRef::embedded(method));
1367            }
1368        }
1369        self
1370    }
1371
1372    /// Adds a service.
1373    #[must_use]
1374    pub fn service(mut self, service: Service) -> Self {
1375        if self.error.is_none() {
1376            self.error = self.document.insert_service(service).err();
1377        }
1378        self
1379    }
1380
1381    /// Adds an extension property; a core property name is refused at
1382    /// [`build`](Self::build) with [`DocumentError::ReservedProperty`].
1383    #[must_use]
1384    pub fn property(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
1385        let name = name.into();
1386        if DidDocument::CORE_PROPERTIES.contains(&name.as_str()) {
1387            if self.error.is_none() {
1388                self.error = Some(DocumentError::ReservedProperty(name));
1389            }
1390        } else {
1391            self.document.properties.insert(name, value.into());
1392        }
1393        self
1394    }
1395
1396    /// The document.
1397    ///
1398    /// # Errors
1399    ///
1400    /// The first [`DocumentError`] an addition raised: a duplicate method or service id.
1401    pub fn build(self) -> Result<DidDocument, DocumentError> {
1402        match self.error {
1403            Some(error) => Err(error),
1404            None => Ok(self.document),
1405        }
1406    }
1407}