identity_kit/did/mod.rs
1//! Decentralized identifiers (DIDs), DID URLs, DID documents and resolution types.
2//!
3//! Pure data: no I/O, no async, no crypto. The module has three parts:
4//!
5//! - **Identifiers.** [`Did`] and [`DidUrl`] implement the DID and DID URL syntax, described
6//! below; [`DidUrlReference`] is a DID URL or a relative reference such as `#key-1`; [`Uri`]
7//! is any RFC 3986 URI, kept as written.
8//! - **Documents.** [`DidDocument`] with [`VerificationMethod`], [`MethodRef`], [`Service`] and
9//! the other types of DID Core §5, serialized deterministically with extension properties in
10//! insertion order, plus the operations to edit and query a document.
11//! - **Resolution.** [`ResolutionResult`], [`DocumentMetadata`], [`ResolutionMetadata`],
12//! [`ResolutionOptions`] and the [`ResolutionError`] vocabulary of DID Core §7.1.
13//!
14//! # DID syntax
15//!
16//! [`Did`] and [`DidUrl`] are validated when constructed and otherwise keep the input unchanged.
17//! They implement the syntax of [W3C DID Core 1.0] §3.1 and §3.2 together with the RFC 3986
18//! productions it references:
19//!
20//! ```text
21//! did = "did:" method-name ":" method-specific-id
22//! method-name = 1*method-char
23//! method-char = %x61-7A / DIGIT ; lowercase a-z and 0-9 only
24//! method-specific-id = *( *idchar ":" ) 1*idchar ; colons allowed, last segment non-empty
25//! idchar = ALPHA / DIGIT / "." / "-" / "_" / pct-encoded
26//! pct-encoded = "%" HEXDIG HEXDIG
27//!
28//! did-url = did path-abempty [ "?" query ] [ "#" fragment ]
29//! ```
30//!
31//! Consequences worth knowing:
32//!
33//! - `did:` and the method name are lowercase and case-sensitive: `DID:example:123` and
34//! `did:Example:123` are invalid.
35//! - The method-specific id may contain `:` and empty inner segments (`did:example:a::b` is valid)
36//! but must not end with `:` (`did:example:a:` is invalid).
37//! - Percent-encoding is checked for completeness (`%3A` valid, `%3` and `%G1` invalid) but never
38//! decoded, and nothing is normalized. Two DIDs are equal exactly when their strings are equal.
39//! - A space, `/`, `?`, `#` or non-ASCII character ends the DID. [`Did::parse`] rejects it;
40//! [`DidUrl::parse`] takes `/`, `?` and `#` as the start of the path, query or fragment.
41//! - Parsing rejects input longer than [`DEFAULT_MAX_LEN`] bytes; use
42//! [`Did::parse_with_max_len`] or [`DidUrl::parse_with_max_len`] to change the limit.
43//!
44//! Both types implement `Display`, `FromStr`, `TryFrom<&str>`, `TryFrom<String>`, `AsRef<str>`,
45//! `Clone`, `Eq`, `Ord`, `Hash`, and serde `Serialize`/`Deserialize` as a plain string, where
46//! deserialization validates.
47//!
48//! # Examples
49//!
50//! ```
51//! use identity_kit::did::{Did, DidUrl};
52//!
53//! let did: Did = "did:example:123".parse()?;
54//! let key = did.join("#key-1")?;
55//! assert_eq!(key.to_string(), "did:example:123#key-1");
56//!
57//! let url = DidUrl::parse("did:example:123/path?versionId=1#key-1")?;
58//! assert_eq!(url.did(), &did);
59//! assert_eq!(url.path(), Some("/path"));
60//! assert_eq!(url.query(), Some("versionId=1"));
61//! assert_eq!(url.fragment(), Some("key-1"));
62//! # Ok::<(), identity_kit::did::DidError>(())
63//! ```
64//!
65//! [W3C DID Core 1.0]: https://www.w3.org/TR/did-core/
66
67mod document;
68mod error;
69mod reference;
70mod resolution;
71mod syntax;
72mod uri;
73
74pub use document::{
75 Context, DidDocument, DidDocumentBuilder, DocumentError, MethodRef, MethodType, OneOrMany,
76 Service, ServiceEndpoint, VerificationMaterial, VerificationMethod, VerificationRelationship,
77};
78pub use error::DidError;
79pub use reference::DidUrlReference;
80pub use resolution::{
81 APPLICATION_DID_JSON, APPLICATION_DID_LD_JSON, DocumentMetadata, ResolutionError,
82 ResolutionMetadata, ResolutionOptions, ResolutionResult,
83};
84pub use syntax::{DEFAULT_MAX_LEN, Did, DidUrl};
85pub use uri::Uri;