identity_did/
did_compositejwk.rs

1// Copyright 2020-2025 IOTA Stiftung, Fondazione Links
2// SPDX-License-Identifier: Apache-2.0
3
4use std::fmt::Debug;
5use std::fmt::Display;
6use std::str::FromStr;
7
8use identity_jose::jwk::CompositeJwk;
9use identity_jose::jwu::decode_b64_json;
10
11use crate::CoreDID;
12use crate::Error;
13use crate::DID;
14
15#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize, serde::Serialize)]
16#[repr(transparent)]
17#[serde(into = "CoreDID", try_from = "CoreDID")]
18/// A type representing a `did:compositejwk` DID.
19pub struct DIDCompositeJwk(CoreDID);
20
21impl DIDCompositeJwk {
22  /// [`DIDCompositeJwk`]'s method.
23  pub const METHOD: &'static str = "compositejwk";
24
25  /// Tries to parse a [`DIDCompositeJwk`] from a string.
26  pub fn parse(s: &str) -> Result<Self, Error> {
27    s.parse()
28  }
29
30  /// Returns the JWK encoded inside this did:jwk.
31  pub fn composite_jwk(&self) -> CompositeJwk {
32    decode_b64_json(self.method_id()).expect("did:compositejwk encodes a valid compositeJwk")
33  }
34}
35
36impl AsRef<CoreDID> for DIDCompositeJwk {
37  fn as_ref(&self) -> &CoreDID {
38    &self.0
39  }
40}
41
42impl From<DIDCompositeJwk> for CoreDID {
43  fn from(value: DIDCompositeJwk) -> Self {
44    value.0
45  }
46}
47
48impl<'a> TryFrom<&'a str> for DIDCompositeJwk {
49  type Error = Error;
50  fn try_from(value: &'a str) -> Result<Self, Self::Error> {
51    value.parse()
52  }
53}
54
55impl Display for DIDCompositeJwk {
56  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57    write!(f, "{}", self.0)
58  }
59}
60
61impl FromStr for DIDCompositeJwk {
62  type Err = Error;
63  fn from_str(s: &str) -> Result<Self, Self::Err> {
64    s.parse::<CoreDID>().and_then(TryFrom::try_from)
65  }
66}
67
68impl From<DIDCompositeJwk> for String {
69  fn from(value: DIDCompositeJwk) -> Self {
70    value.to_string()
71  }
72}
73
74impl TryFrom<CoreDID> for DIDCompositeJwk {
75  type Error = Error;
76  fn try_from(value: CoreDID) -> Result<Self, Self::Error> {
77    let Self::METHOD = value.method() else {
78      return Err(Error::InvalidMethodName);
79    };
80    decode_b64_json::<CompositeJwk>(value.method_id())
81      .map(|_| Self(value))
82      .map_err(|_| Error::InvalidMethodId)
83  }
84}