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