datex_core/values/
pointer.rs1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5pub enum PointerAddress {
6 Local([u8; 5]),
9 Remote([u8; 26]),
11 Internal([u8; 3]), }
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}