Skip to main content

datex_core/values/
pointer.rs

1use crate::{
2    global::protocol_structures::instructions::{
3        RawInternalPointerAddress, RawPointerAddress,
4    },
5    prelude::*,
6};
7
8use crate::global::protocol_structures::instructions::{
9    RawFullPointerAddress, RawLocalPointerAddress,
10};
11use core::{fmt::Display, result::Result};
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub enum PointerAddress {
16    // pointer with the local endpoint as origin
17    // the full pointer id consists of the local endpoint id + this local id
18    Local([u8; 5]),
19    // pointer with a remote endpoint as origin, contains the full pointers address
20    Remote([u8; 26]),
21    // globally unique internal pointer, e.g. for #core, #std
22    Internal([u8; 3]), // TODO #312 shrink down to 2 bytes?
23}
24
25impl TryFrom<String> for PointerAddress {
26    type Error = &'static str;
27    fn try_from(s: String) -> Result<Self, Self::Error> {
28        PointerAddress::try_from(s.as_str())
29    }
30}
31impl TryFrom<&str> for PointerAddress {
32    type Error = &'static str;
33    fn try_from(s: &str) -> Result<Self, Self::Error> {
34        let hex_str = if let Some(stripped) = s.strip_prefix('$') {
35            stripped
36        } else {
37            s
38        };
39        let bytes = hex::decode(hex_str).map_err(|_| "Invalid hex string")?;
40        match bytes.len() {
41            5 => {
42                let mut arr = [0u8; 5];
43                arr.copy_from_slice(&bytes);
44                Ok(PointerAddress::Local(arr))
45            }
46            26 => {
47                let mut arr = [0u8; 26];
48                arr.copy_from_slice(&bytes);
49                Ok(PointerAddress::Remote(arr))
50            }
51            3 => {
52                let mut arr = [0u8; 3];
53                arr.copy_from_slice(&bytes);
54                Ok(PointerAddress::Internal(arr))
55            }
56            _ => Err("PointerAddress must be 5, 26 or 3 bytes long"),
57        }
58    }
59}
60
61impl From<RawPointerAddress> for PointerAddress {
62    fn from(raw: RawPointerAddress) -> Self {
63        PointerAddress::from(&raw)
64    }
65}
66
67impl From<&RawLocalPointerAddress> for PointerAddress {
68    fn from(raw: &RawLocalPointerAddress) -> Self {
69        PointerAddress::Local(raw.id)
70    }
71}
72
73impl From<&RawInternalPointerAddress> for PointerAddress {
74    fn from(raw: &RawInternalPointerAddress) -> Self {
75        PointerAddress::Internal(raw.id)
76    }
77}
78
79impl From<&RawFullPointerAddress> for PointerAddress {
80    fn from(raw: &RawFullPointerAddress) -> Self {
81        PointerAddress::Remote(raw.id)
82    }
83}
84
85impl From<&RawPointerAddress> for PointerAddress {
86    fn from(raw: &RawPointerAddress) -> Self {
87        match raw {
88            RawPointerAddress::Local(bytes) => PointerAddress::Local(bytes.id),
89            RawPointerAddress::Internal(bytes) => {
90                PointerAddress::Internal(bytes.id)
91            }
92            RawPointerAddress::Full(bytes) => PointerAddress::Remote(bytes.id),
93        }
94    }
95}
96
97impl PointerAddress {
98    pub fn to_address_string(&self) -> String {
99        match self {
100            PointerAddress::Local(bytes) => hex::encode(bytes),
101            PointerAddress::Remote(bytes) => hex::encode(bytes),
102            PointerAddress::Internal(bytes) => hex::encode(bytes),
103        }
104    }
105}
106
107impl Display for PointerAddress {
108    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109        core::write!(f, "$")?;
110        core::write!(f, "{}", self.to_address_string())
111    }
112}
113impl Serialize for PointerAddress {
114    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115    where
116        S: serde::Serializer,
117    {
118        let addr_str = self.to_address_string();
119        serializer.serialize_str(&addr_str)
120    }
121}
122impl<'de> Deserialize<'de> for PointerAddress {
123    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124    where
125        D: serde::Deserializer<'de>,
126    {
127        let s = String::deserialize(deserializer)?;
128        PointerAddress::try_from(s.as_str()).map_err(|e| {
129            serde::de::Error::custom(format!(
130                "Failed to parse PointerAddress: {}",
131                e
132            ))
133        })
134    }
135}
136
137impl PointerAddress {
138    pub fn bytes(&self) -> &[u8] {
139        match self {
140            PointerAddress::Local(bytes) => bytes,
141            PointerAddress::Remote(bytes) => bytes,
142            PointerAddress::Internal(bytes) => bytes,
143        }
144    }
145}