1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use crate::Error;
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Clone)]
pub struct AgentId {
    // #[serde(
    //     serialize_with = "mindbase_util::serde_helper::as_base64",
    //     deserialize_with = "mindbase_util::serde_helper::from_base64_32"
    // )]
    pub pubkey: [u8; 32],
}

impl AgentId {
    pub fn pubkey_short(&self) -> String {
        use base64::STANDARD_NO_PAD;
        base64::encode_config(&self.pubkey[0..12], STANDARD_NO_PAD)
    }

    pub fn from_base64(input: &str) -> Result<Self, Error> {
        use std::convert::TryInto;
        let decoded = base64::decode(input).map_err(|_| Error::Base64Error)?;
        let array: [u8; 32] = decoded[..]
            .try_into()
            .map_err(|_| crate::Error::TryFromSlice)?;
        Ok(AgentId {
            pubkey: array.into(),
        })
    }
}

impl crate::util::AsBytes for &AgentId {
    fn as_bytes(&self) -> Vec<u8> {
        self.pubkey[..].to_vec()
    }
}
impl std::convert::AsRef<[u8]> for AgentId {
    fn as_ref(&self) -> &[u8] {
        &self.pubkey[..]
    }
}

impl fmt::Display for AgentId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.pubkey_short())
    }
}
impl fmt::Debug for AgentId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "AgentId:{}", &self.pubkey_short())
    }
}

#[derive(Clone, Serialize, Deserialize)]
pub struct AgentIdentity {
    pub pubkey: [u8; 32],
    pub email: Option<String>,
}

impl AgentIdentity {
    pub fn pubkey_base64(&self) -> String {
        base64::encode_config(&self.pubkey[..], base64::STANDARD_NO_PAD)
    }
}

impl fmt::Display for AgentIdentity {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let string = base64::encode_config(&self.pubkey[..], base64::STANDARD_NO_PAD);
        write!(
            f,
            "{} ({})",
            &string,
            self.email.as_ref().map(|v| &v[..]).unwrap_or("-" as &str)
        )
    }
}

#[cfg(test)]
mod test {
    use super::AgentId;

    #[test]
    fn serde() {
        let id = AgentId { pubkey: [0; 32] };
        let bytes = bincode::serialize(&id).unwrap();
        let id2: AgentId = bincode::deserialize(&bytes).unwrap();

        assert_eq!(id, id2);
    }
}