datex_core/values/
pointer.rs

1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5pub enum PointerAddress {
6    // pointer with the local endpoint as origin
7    // the full pointer id consists of the local endpoint id + this local id
8    Local([u8; 5]),
9    // pointer with a remote endpoint as origin, contains the full pointers address
10    Remote([u8; 26]),
11    // globally unique internal pointer, e.g. for #core, #std
12    Internal([u8; 3]), // TODO #312 shrink down to 2 bytes?
13}
14impl TryFrom<String> for PointerAddress {
15    type Error = &'static str;
16    fn try_from(s: String) -> Result<Self, Self::Error> {
17        PointerAddress::try_from(s.as_str())
18    }
19}
20impl TryFrom<&str> for PointerAddress {
21    type Error = &'static str;
22    fn try_from(s: &str) -> Result<Self, Self::Error> {
23        let hex_str = if let Some(stripped) = s.strip_prefix('$') {
24            stripped
25        } else {
26            s
27        };
28        let bytes = hex::decode(hex_str).map_err(|_| "Invalid hex string")?;
29        match bytes.len() {
30            5 => {
31                let mut arr = [0u8; 5];
32                arr.copy_from_slice(&bytes);
33                Ok(PointerAddress::Local(arr))
34            }
35            26 => {
36                let mut arr = [0u8; 26];
37                arr.copy_from_slice(&bytes);
38                Ok(PointerAddress::Remote(arr))
39            }
40            3 => {
41                let mut arr = [0u8; 3];
42                arr.copy_from_slice(&bytes);
43                Ok(PointerAddress::Internal(arr))
44            }
45            _ => Err("PointerAddress must be 5, 26 or 3 bytes long"),
46        }
47    }
48}
49
50impl PointerAddress {
51    pub fn to_address_string(&self) -> String {
52        match self {
53            PointerAddress::Local(bytes) => hex::encode(bytes),
54            PointerAddress::Remote(bytes) => hex::encode(bytes),
55            PointerAddress::Internal(bytes) => hex::encode(bytes),
56        }
57    }
58}
59
60impl Display for PointerAddress {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        write!(f, "$")?;
63        write!(f, "{}", self.to_address_string())
64    }
65}
66impl Serialize for PointerAddress {
67    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68    where
69        S: serde::Serializer,
70    {
71        let addr_str = self.to_address_string();
72        serializer.serialize_str(&addr_str)
73    }
74}
75impl<'de> Deserialize<'de> for PointerAddress {
76    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77    where
78        D: serde::Deserializer<'de>,
79    {
80        let s = String::deserialize(deserializer)?;
81        PointerAddress::try_from(s.as_str()).map_err(|e| {
82            serde::de::Error::custom(format!(
83                "Failed to parse PointerAddress: {}",
84                e
85            ))
86        })
87    }
88}
89
90impl PointerAddress {
91    pub fn bytes(&self) -> &[u8] {
92        match self {
93            PointerAddress::Local(bytes) => bytes,
94            PointerAddress::Remote(bytes) => bytes,
95            PointerAddress::Internal(bytes) => bytes,
96        }
97    }
98}