ssi_dids_core/document/
verification_method.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use ssi_verification_methods_core::GenericVerificationMethod;
5
6use crate::{DIDBuf, DIDURLBuf, DIDURLReference, DIDURLReferenceBuf, DID, DIDURL};
7
8use super::{
9    resource::{ExtractResource, FindResource, Resource, UsesResource},
10    ResourceRef,
11};
12
13/// Reference to, or value of, a verification method.
14#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
15#[serde(rename_all = "camelCase")]
16#[serde(untagged)]
17#[allow(clippy::large_enum_variant)]
18pub enum ValueOrReference {
19    Reference(DIDURLReferenceBuf),
20    /// Embedded verification method.
21    Value(DIDVerificationMethod),
22}
23
24impl ValueOrReference {
25    pub fn id(&self) -> DIDURLReference {
26        match self {
27            Self::Reference(r) => r.as_did_reference(),
28            Self::Value(v) => DIDURLReference::Absolute(&v.id),
29        }
30    }
31
32    pub fn as_value(&self) -> Option<&DIDVerificationMethod> {
33        match self {
34            Self::Value(v) => Some(v),
35            _ => None,
36        }
37    }
38}
39
40impl From<DIDURLBuf> for ValueOrReference {
41    fn from(value: DIDURLBuf) -> Self {
42        Self::Reference(value.into())
43    }
44}
45
46impl From<DIDURLReferenceBuf> for ValueOrReference {
47    fn from(value: DIDURLReferenceBuf) -> Self {
48        Self::Reference(value)
49    }
50}
51
52impl From<DIDVerificationMethod> for ValueOrReference {
53    fn from(value: DIDVerificationMethod) -> Self {
54        Self::Value(value)
55    }
56}
57
58impl UsesResource for ValueOrReference {
59    fn uses_resource(&self, base_id: &DID, id: &DIDURL) -> bool {
60        match self {
61            Self::Reference(r) => *r.resolve(base_id) == *id,
62            Self::Value(v) => v.uses_resource(base_id, id),
63        }
64    }
65}
66
67impl FindResource for ValueOrReference {
68    fn find_resource(&self, base_did: &DID, id: &DIDURL) -> Option<ResourceRef> {
69        match self {
70            Self::Reference(_) => None,
71            Self::Value(m) => m.find_resource(base_did, id),
72        }
73    }
74}
75
76impl ExtractResource for ValueOrReference {
77    fn extract_resource(self, base_did: &DID, id: &DIDURL) -> Option<Resource> {
78        match self {
79            Self::Reference(_) => None,
80            Self::Value(m) => m.extract_resource(base_did, id),
81        }
82    }
83}
84
85#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
86pub struct DIDVerificationMethod {
87    /// Verification method identifier.
88    pub id: DIDURLBuf,
89
90    /// type [property](https://www.w3.org/TR/did-core/#dfn-did-urls) of a verification method map.
91    /// Should be registered in [DID Specification
92    /// registries - Verification method types](https://www.w3.org/TR/did-spec-registries/#verification-method-types).
93    #[serde(rename = "type")]
94    pub type_: String,
95
96    // Note: different than when the DID Document is the subject:
97    //    The value of the controller property, which identifies the
98    //    controller of the corresponding private key, MUST be a valid DID.
99    /// [controller](https://w3c-ccg.github.io/ld-proofs/#controller) property of a verification
100    /// method map.
101    ///
102    /// Not to be confused with the [controller](https://www.w3.org/TR/did-core/#dfn-controller) property of a DID document.
103    pub controller: DIDBuf,
104
105    /// Verification methods properties.
106    #[serde(flatten)]
107    pub properties: BTreeMap<String, serde_json::Value>,
108}
109
110impl DIDVerificationMethod {
111    pub fn new(
112        id: DIDURLBuf,
113        type_: String,
114        controller: DIDBuf,
115        properties: BTreeMap<String, serde_json::Value>,
116    ) -> Self {
117        Self {
118            id,
119            type_,
120            controller,
121            properties,
122        }
123    }
124}
125
126impl From<DIDVerificationMethod> for GenericVerificationMethod {
127    fn from(value: DIDVerificationMethod) -> Self {
128        GenericVerificationMethod {
129            id: value.id.into(),
130            type_: value.type_,
131            controller: value.controller.into(),
132            properties: value.properties,
133        }
134    }
135}
136
137impl UsesResource for DIDVerificationMethod {
138    fn uses_resource(&self, _base_did: &DID, id: &DIDURL) -> bool {
139        self.id == *id
140    }
141}
142
143impl FindResource for DIDVerificationMethod {
144    fn find_resource(&self, _base_did: &DID, id: &DIDURL) -> Option<ResourceRef> {
145        if self.id == *id {
146            Some(ResourceRef::VerificationMethod(self))
147        } else {
148            None
149        }
150    }
151}
152
153impl ExtractResource for DIDVerificationMethod {
154    fn extract_resource(self, _base_did: &DID, id: &DIDURL) -> Option<Resource> {
155        if self.id == *id {
156            Some(Resource::VerificationMethod(self))
157        } else {
158            None
159        }
160    }
161}