typesec_integrations/did/
identifier.rs1use std::fmt;
4
5use serde::{Deserialize, Serialize};
6
7use super::crypto::hex_encode;
8use super::error::DidError;
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(try_from = "String", into = "String")]
13pub struct Did(String);
14
15impl Did {
16 pub fn parse(value: impl Into<String>) -> Result<Self, DidError> {
18 let value = value.into();
19 let parts: Vec<_> = value.split(':').collect();
20 if parts.len() < 3 || parts.first() != Some(&"did") || parts[1].is_empty() {
21 return Err(DidError::InvalidDid(value));
22 }
23 Ok(Self(value))
24 }
25
26 pub fn key(public_key: impl AsRef<[u8]>) -> Self {
28 Self(format!("did:key:z{}", hex_encode(public_key.as_ref())))
29 }
30
31 pub fn web(host: impl AsRef<str>) -> Result<Self, DidError> {
33 let host = host.as_ref().trim();
34 if host.is_empty() || host.contains('/') {
35 return Err(DidError::InvalidDid(format!("did:web:{host}")));
36 }
37 Ok(Self(format!("did:web:{host}")))
38 }
39
40 pub fn as_str(&self) -> &str {
42 &self.0
43 }
44}
45
46impl fmt::Display for Did {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.write_str(&self.0)
49 }
50}
51
52impl TryFrom<String> for Did {
53 type Error = DidError;
54
55 fn try_from(value: String) -> Result<Self, Self::Error> {
56 Self::parse(value)
57 }
58}
59
60impl From<Did> for String {
61 fn from(value: Did) -> Self {
62 value.0
63 }
64}