ruma_common/identifiers/
base64_public_key.rs

1use ruma_macros::IdZst;
2
3use super::{IdParseError, KeyName};
4use crate::serde::{base64::Standard, Base64, Base64DecodeError};
5
6/// A public key encoded using unpadded base64, used as an identifier for [cross-signing] keys.
7///
8/// This string is validated using the set `[a-zA-Z0-9+/=]`, but it is not validated to be decodable
9/// as base64. This type is provided simply for its semantic value.
10///
11/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
12#[repr(transparent)]
13#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)]
14#[ruma_id(validate = ruma_identifiers_validation::base64_public_key::validate)]
15pub struct Base64PublicKey(str);
16
17impl OwnedBase64PublicKey {
18    /// Construct a new `OwnedBase64PublicKey` by encoding the given bytes using unpadded base64.
19    pub fn with_bytes<B: AsRef<[u8]>>(bytes: B) -> OwnedBase64PublicKey {
20        Base64::<Standard, B>::new(bytes).into()
21    }
22}
23
24impl KeyName for Base64PublicKey {
25    fn validate(s: &str) -> Result<(), IdParseError> {
26        ruma_identifiers_validation::base64_public_key::validate(s)
27    }
28}
29
30impl KeyName for OwnedBase64PublicKey {
31    fn validate(s: &str) -> Result<(), IdParseError> {
32        ruma_identifiers_validation::base64_public_key::validate(s)
33    }
34}
35
36impl<B: AsRef<[u8]>> From<Base64<Standard, B>> for OwnedBase64PublicKey {
37    fn from(value: Base64<Standard, B>) -> Self {
38        value.to_string().try_into().unwrap_or_else(|_| unreachable!())
39    }
40}
41
42impl TryFrom<&Base64PublicKey> for Base64<Standard, Vec<u8>> {
43    type Error = Base64DecodeError;
44
45    fn try_from(value: &Base64PublicKey) -> Result<Self, Self::Error> {
46        Base64::parse(value)
47    }
48}
49
50impl TryFrom<&OwnedBase64PublicKey> for Base64<Standard, Vec<u8>> {
51    type Error = Base64DecodeError;
52
53    fn try_from(value: &OwnedBase64PublicKey) -> Result<Self, Self::Error> {
54        Base64::parse(value)
55    }
56}
57
58impl TryFrom<OwnedBase64PublicKey> for Base64<Standard, Vec<u8>> {
59    type Error = Base64DecodeError;
60
61    fn try_from(value: OwnedBase64PublicKey) -> Result<Self, Self::Error> {
62        Base64::parse(value)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::{Base64PublicKey, OwnedBase64PublicKey};
69
70    #[test]
71    fn valid_string() {
72        <&Base64PublicKey>::try_from("base64+master+public+key").unwrap();
73    }
74
75    #[test]
76    fn invalid_string() {
77        <&Base64PublicKey>::try_from("not@base@64").unwrap_err();
78    }
79
80    #[test]
81    fn constructor() {
82        _ = OwnedBase64PublicKey::with_bytes(b"self-signing master public key");
83    }
84}