Skip to main content

core_crypto/mls/session/id/
qualified.rs

1use wire_e2e_identity::E2eiClientId;
2
3use crate::{
4    ClientId,
5    mls::session::{Error, Result},
6};
7
8/// This type wraps [ClientId] and verifies upon instantiation that it conforms to the `<userid>-<device-id>@<domain>`
9/// format.
10///
11/// [E2eiClientId] would have been antoher natural canditate to wrap, since it holds the triple data internally.
12/// However, this type is intended to be used as a [ClientId] more often than it is to be used as [E2eiClientId], so it
13/// should deref to the former.
14#[derive(
15    core_crypto_macros::Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
16)]
17pub struct QualifiedClientId(ClientId);
18
19impl TryFrom<ClientId> for QualifiedClientId {
20    type Error = Error;
21
22    /// Ensure that parsing to an [E2eiClientId] succeeds.
23    fn try_from(value: ClientId) -> Result<Self> {
24        let _client_id = Self::try_parse(&value)?;
25        Ok(Self(value))
26    }
27}
28
29impl QualifiedClientId {
30    /// Try cloning a [ClientId] into an [E2eiClientId].
31    pub fn try_parse(value: &ClientId) -> Result<E2eiClientId> {
32        let client_id = std::str::from_utf8(value.as_ref()).map_err(|_| Error::InvalidQualifiedClientId)?;
33        wire_e2e_identity::E2eiClientId::try_from_qualified(client_id).map_err(|_| Error::InvalidQualifiedClientId)
34    }
35
36    /// Clone the data into an [E2eiClientId].
37    pub fn as_e2ei_client_id(&self) -> E2eiClientId {
38        Self::try_parse(&self.0).expect("We verified that this succeeds on instantiation")
39    }
40}