core_crypto/mls/session/
id.rs

1use super::error::Error;
2
3/// A Client identifier
4///
5/// A unique identifier for clients. A client is an identifier for each App a user is using, such as desktop,
6/// mobile, etc. Users can have multiple clients.
7/// More information [here](https://messaginglayersecurity.rocks/mls-architecture/draft-ietf-mls-architecture.html#name-group-members-and-clients)
8#[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::Deref)]
9pub struct ClientId(pub(crate) Vec<u8>);
10
11impl From<&[u8]> for ClientId {
12    fn from(value: &[u8]) -> Self {
13        Self(value.into())
14    }
15}
16
17impl From<Vec<u8>> for ClientId {
18    fn from(value: Vec<u8>) -> Self {
19        Self(value)
20    }
21}
22
23impl From<Box<[u8]>> for ClientId {
24    fn from(value: Box<[u8]>) -> Self {
25        Self(value.into())
26    }
27}
28
29impl From<ClientId> for Box<[u8]> {
30    fn from(value: ClientId) -> Self {
31        value.0.into_boxed_slice()
32    }
33}
34
35#[cfg(test)]
36impl From<&str> for ClientId {
37    fn from(value: &str) -> Self {
38        Self(value.as_bytes().into())
39    }
40}
41
42#[allow(clippy::from_over_into)]
43impl Into<Vec<u8>> for ClientId {
44    fn into(self) -> Vec<u8> {
45        self.0
46    }
47}
48
49impl std::fmt::Display for ClientId {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        write!(f, "{}", hex::encode(self.0.as_slice()))
52    }
53}
54
55impl std::str::FromStr for ClientId {
56    type Err = Error;
57
58    fn from_str(s: &str) -> Result<Self, Self::Err> {
59        Ok(Self(
60            hex::decode(s).map_or_else(|_| s.as_bytes().to_vec(), std::convert::identity),
61        ))
62    }
63}