ssi_verification_methods_core/
methods.rs

1use std::collections::BTreeMap;
2
3use iref::{IriBuf, UriBuf};
4
5use crate::{TypedVerificationMethod, VerificationMethod};
6
7/// Generic verification method.
8#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
9pub struct GenericVerificationMethod {
10    /// Identifier.
11    pub id: IriBuf,
12
13    /// Type name.
14    #[serde(rename = "type")]
15    pub type_: String,
16
17    /// Method controller.
18    pub controller: UriBuf,
19
20    /// Other properties.
21    #[serde(flatten)]
22    pub properties: BTreeMap<String, serde_json::Value>,
23}
24
25impl VerificationMethod for GenericVerificationMethod {
26    fn id(&self) -> &iref::Iri {
27        &self.id
28    }
29
30    fn controller(&self) -> Option<&iref::Iri> {
31        Some(self.controller.as_iri())
32    }
33}
34
35impl TypedVerificationMethod for GenericVerificationMethod {
36    fn type_(&self) -> &str {
37        &self.type_
38    }
39
40    fn expected_type() -> Option<crate::ExpectedType> {
41        None
42    }
43
44    fn type_match(_ty: &str) -> bool {
45        true
46    }
47}
48
49#[macro_export]
50macro_rules! verification_method_union {
51	{
52		$vis:vis enum $name:ident, $kind:ident {
53			$(
54				$(#[$meta:meta])*
55				$variant:ident
56			),*
57		}
58	} => {
59		#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, linked_data::Serialize, linked_data::Deserialize)]
60		$vis enum $name {
61			$(
62				$(#[$meta])*
63				$variant($variant)
64			),*
65		}
66
67		impl $crate::VerificationMethodSet for $name {
68			type TypeSet = &'static [&'static str];
69
70			fn type_set() -> Self::TypeSet {
71				&[
72					$(
73						$(#[$meta])*
74						$variant::NAME
75					),*
76				]
77			}
78		}
79
80		#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
81		$vis enum $kind {
82			$(
83				$(#[$meta])*
84				$variant
85			),*
86		}
87
88		impl $kind {
89			pub fn iri(&self) -> &iref::Iri {
90				match self {
91					$(
92						$(#[$meta])*
93						Self::$variant => $variant::IRI
94					),*
95				}
96			}
97		}
98
99		impl $name {
100			pub fn type_(&self) -> $kind {
101				match self {
102					$(
103						$(#[$meta])*
104						Self::$variant(_) => $kind::$variant
105					),*
106				}
107			}
108		}
109
110		impl $crate::VerificationMethod for $name {
111			fn id(&self) -> &iref::Iri {
112				match self {
113					$(
114						$(#[$meta])*
115						Self::$variant(m) => m.id()
116					),*
117				}
118			}
119
120			fn controller(&self) -> Option<&iref::Iri> {
121				match self {
122					$(
123						$(#[$meta])*
124						Self::$variant(m) => m.controller()
125					),*
126				}
127			}
128		}
129
130		impl $crate::TypedVerificationMethod for $name {
131			fn expected_type() -> Option<$crate::ExpectedType> {
132				let mut types = Vec::new();
133
134				$(
135					$(#[$meta])*
136					match $variant::expected_type() {
137						Some($crate::ExpectedType::One(t)) => types.push(t),
138						Some($crate::ExpectedType::Many(ts)) => types.extend(ts),
139						None => ()
140					}
141				)*
142
143				match types.len() {
144					0 => None,
145					1 => Some($crate::ExpectedType::One(types.pop().unwrap())),
146					_ => Some($crate::ExpectedType::Many(types))
147				}
148			}
149
150			fn type_match(ty: &str) -> bool {
151				$(
152					$(#[$meta])*
153					if <$variant as $crate::TypedVerificationMethod>::type_match(ty) {
154						return true
155					}
156				)*
157
158				false
159			}
160
161			fn type_(&self) -> &str {
162				match self {
163					$(
164						$(#[$meta])*
165						Self::$variant(m) => m.type_()
166					),*
167				}
168			}
169		}
170
171		$(
172			$(#[$meta])*
173			impl TryFrom<$name> for $variant {
174				type Error = $crate::InvalidVerificationMethod;
175
176				fn try_from(value: $name) -> Result<Self, Self::Error> {
177					match value {
178						$name::$variant(m) => Ok(m),
179						other => Err($crate::InvalidVerificationMethod::invalid_type_iri(other.type_().iri()))
180					}
181				}
182			}
183
184			$(#[$meta])*
185			impl From<$variant> for $name {
186				fn from(value: $variant) -> Self {
187					Self::$variant(value)
188				}
189			}
190		)*
191
192		impl TryFrom<$crate::GenericVerificationMethod> for $name {
193			type Error = $crate::InvalidVerificationMethod;
194
195			fn try_from(value: $crate::GenericVerificationMethod) -> Result<Self, Self::Error> {
196				$(
197					$(#[$meta])*
198					if <$variant as $crate::TypedVerificationMethod>::type_match(&value.type_) {
199						return <$variant as TryFrom<$crate::GenericVerificationMethod>>::try_from(value).map(Self::$variant)
200					}
201				)*
202
203				Err($crate::InvalidVerificationMethod::UnsupportedMethodType(value.type_))
204			}
205		}
206	};
207}
208
209#[macro_export]
210macro_rules! complete_verification_method_union {
211	{
212		$vis:vis enum $name:ident, $kind:ident, $kind_ref:ident {
213			$(
214				$(#[$meta:meta])*
215				$variant:ident
216			),*
217		}
218	} => {
219		#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, linked_data::Serialize, linked_data::Deserialize)]
220		#[serde(untagged)]
221		$vis enum $name {
222			$(
223				$(#[$meta])*
224				$variant($variant),
225			)*
226			Unknown(GenericVerificationMethod)
227		}
228
229		impl $crate::VerificationMethodSet for $name {
230			type TypeSet = &'static [&'static str];
231
232			fn type_set() -> Self::TypeSet {
233				&[
234					$(
235						$(#[$meta])*
236						$variant::NAME
237					),*
238				]
239			}
240		}
241
242		#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
243		$vis enum $kind {
244			$(
245				$(#[$meta])*
246				$variant,
247			)*
248			Unknown(String)
249		}
250
251		impl $kind {
252			pub fn name(&self) -> &str {
253				match self {
254					$(
255						$(#[$meta])*
256						Self::$variant => $variant::NAME,
257					)*
258					Self::Unknown(name) => name
259				}
260			}
261		}
262
263		#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
264		$vis enum $kind_ref<'a> {
265			$(
266				$(#[$meta])*
267				$variant,
268			)*
269			Unknown(&'a str)
270		}
271
272		impl<'a> $kind_ref<'a> {
273			pub fn name(&self) -> &'a str {
274				match self {
275					$(
276						$(#[$meta])*
277						Self::$variant => $variant::NAME,
278					)*
279					Self::Unknown(name) => name
280				}
281			}
282		}
283
284		impl $name {
285			pub fn type_(&self) -> $kind_ref {
286				match self {
287					$(
288						$(#[$meta])*
289						Self::$variant(_) => $kind_ref::$variant,
290					)*
291					Self::Unknown(m) => $kind_ref::Unknown(&m.type_)
292				}
293			}
294		}
295
296		impl $crate::VerificationMethod for $name {
297			fn id(&self) -> &iref::Iri {
298				match self {
299					$(
300						$(#[$meta])*
301						Self::$variant(m) => m.id(),
302					)*
303					Self::Unknown(m) => &m.id
304				}
305			}
306
307			fn controller(&self) -> Option<&iref::Iri> {
308				match self {
309					$(
310						$(#[$meta])*
311						Self::$variant(m) => m.controller(),
312					)*
313					Self::Unknown(m) => Some(m.controller.as_iri())
314				}
315			}
316		}
317
318		impl $crate::TypedVerificationMethod for $name {
319			fn expected_type() -> Option<$crate::ExpectedType> {
320				None
321			}
322
323			fn type_match(_: &str) -> bool {
324				true
325			}
326
327			fn type_(&self) -> &str {
328				match self {
329					$(
330						$(#[$meta])*
331						Self::$variant(m) => m.type_(),
332					)*
333					Self::Unknown(m) => &m.type_
334				}
335			}
336		}
337
338		$(
339			$(#[$meta])*
340			impl TryFrom<$name> for $variant {
341				type Error = $crate::InvalidVerificationMethod;
342
343				fn try_from(value: $name) -> Result<Self, Self::Error> {
344					use ssi_verification_methods_core::VerificationMethodSet;
345					match value {
346						$name::$variant(m) => Ok(m),
347						other => Err($crate::InvalidVerificationMethod::invalid_type_name(other.type_().name(), Self::type_set()))
348					}
349				}
350			}
351
352			$(#[$meta])*
353			impl From<$variant> for $name {
354				fn from(value: $variant) -> Self {
355					Self::$variant(value)
356				}
357			}
358		)*
359
360		impl TryFrom<$crate::GenericVerificationMethod> for $name {
361			type Error = $crate::InvalidVerificationMethod;
362
363			fn try_from(value: $crate::GenericVerificationMethod) -> Result<Self, Self::Error> {
364				$(
365					$(#[$meta])*
366					if <$variant as $crate::TypedVerificationMethod>::type_match(&value.type_) {
367						return <$variant as TryFrom<$crate::GenericVerificationMethod>>::try_from(value)
368							.map(Self::$variant)
369					}
370				)*
371
372				Ok(Self::Unknown(value))
373			}
374		}
375	};
376}