ruma_common/identifiers/
base64_public_key_or_device_id.rs

1use ruma_macros::IdDst;
2
3use super::{
4    Base64PublicKey, DeviceId, IdParseError, KeyName, OwnedBase64PublicKey, OwnedDeviceId,
5};
6
7/// A Matrix ID that can be either a [`DeviceId`] or a [`Base64PublicKey`].
8///
9/// Device identifiers in Matrix are completely opaque character sequences and cross-signing keys
10/// are identified by their base64-encoded public key. This type is provided simply for its semantic
11/// value.
12///
13/// It is not recommended to construct this type directly, it should instead be converted from a
14/// [`DeviceId`] or a [`Base64PublicKey`].
15///
16/// # Example
17///
18/// ```
19/// use ruma_common::{Base64PublicKeyOrDeviceId, OwnedBase64PublicKeyOrDeviceId};
20///
21/// let ref_id: &Base64PublicKeyOrDeviceId = "abcdefghi".into();
22/// assert_eq!(ref_id.as_str(), "abcdefghi");
23///
24/// let owned_id: OwnedBase64PublicKeyOrDeviceId = "ijklmnop".into();
25/// assert_eq!(owned_id.as_str(), "ijklmnop");
26/// ```
27#[repr(transparent)]
28#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdDst)]
29pub struct Base64PublicKeyOrDeviceId(str);
30
31impl KeyName for Base64PublicKeyOrDeviceId {
32    fn validate(_s: &str) -> Result<(), IdParseError> {
33        Ok(())
34    }
35}
36
37impl KeyName for OwnedBase64PublicKeyOrDeviceId {
38    fn validate(_s: &str) -> Result<(), IdParseError> {
39        Ok(())
40    }
41}
42
43impl<'a> From<&'a DeviceId> for &'a Base64PublicKeyOrDeviceId {
44    fn from(value: &'a DeviceId) -> Self {
45        Self::from(value.as_str())
46    }
47}
48
49impl From<OwnedDeviceId> for OwnedBase64PublicKeyOrDeviceId {
50    fn from(value: OwnedDeviceId) -> Self {
51        unsafe { Self::from_inner_unchecked(value.into_inner()) }
52    }
53}
54
55impl<'a> From<&'a Base64PublicKey> for &'a Base64PublicKeyOrDeviceId {
56    fn from(value: &'a Base64PublicKey) -> Self {
57        Self::from(value.as_str())
58    }
59}
60
61impl From<OwnedBase64PublicKey> for OwnedBase64PublicKeyOrDeviceId {
62    fn from(value: OwnedBase64PublicKey) -> Self {
63        unsafe { Self::from_inner_unchecked(value.into_inner()) }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::OwnedBase64PublicKeyOrDeviceId;
70    use crate::{OwnedBase64PublicKey, OwnedDeviceId};
71
72    #[test]
73    fn convert_owned_device_id_to_owned_base64_public_key_or_device_id() {
74        let device_id: OwnedDeviceId = "MYDEVICE".into();
75        let mixed: OwnedBase64PublicKeyOrDeviceId = device_id.into();
76
77        assert_eq!(mixed.as_str(), "MYDEVICE");
78    }
79
80    #[test]
81    fn convert_owned_base64_public_key_to_owned_base64_public_key_or_device_id() {
82        let base64_public_key: OwnedBase64PublicKey =
83            "base64+master+public+key".try_into().unwrap();
84        let mixed: OwnedBase64PublicKeyOrDeviceId = base64_public_key.into();
85
86        assert_eq!(mixed.as_str(), "base64+master+public+key");
87    }
88}