datex_core/values/
pointer.rs

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