datex_core/shared_values/
pointer_address.rs1use crate::{
2 global::protocol_structures::instructions::{
3 RawInternalPointerAddress, RawPointerAddress,
4 },
5 prelude::*,
6};
7
8use crate::global::protocol_structures::instructions::{
9 RawLocalPointerAddress, RawRemotePointerAddress,
10};
11use core::{fmt::Display, result::Result};
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct OwnedPointerAddress {
16 pub(crate) address: [u8; 5],
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub enum ReferencedPointerAddress {
21 Remote([u8; 26]),
23 Internal([u8; 3]), }
26
27impl OwnedPointerAddress {
28 pub fn new(address: [u8; 5]) -> Self {
29 OwnedPointerAddress { address }
30 }
31
32 pub const NULL: OwnedPointerAddress =
33 OwnedPointerAddress { address: [0u8; 5] };
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Hash)]
37pub enum PointerAddress {
38 Owned(OwnedPointerAddress),
41 Referenced(ReferencedPointerAddress),
43}
44
45impl PointerAddress {
46 pub const NULL: PointerAddress =
47 PointerAddress::Owned(OwnedPointerAddress::NULL);
48
49 pub fn owned(address: [u8; 5]) -> Self {
50 PointerAddress::Owned(OwnedPointerAddress::new(address))
51 }
52
53 pub fn internal(address: [u8; 3]) -> Self {
54 PointerAddress::Referenced(ReferencedPointerAddress::Internal(address))
55 }
56
57 pub fn remote(address: [u8; 26]) -> Self {
58 PointerAddress::Referenced(ReferencedPointerAddress::Remote(address))
59 }
60}
61
62impl TryFrom<String> for PointerAddress {
63 type Error = &'static str;
64 fn try_from(s: String) -> Result<Self, Self::Error> {
65 PointerAddress::try_from(s.as_str())
66 }
67}
68impl TryFrom<&str> for PointerAddress {
69 type Error = &'static str;
70 fn try_from(s: &str) -> Result<Self, Self::Error> {
71 let hex_str = if let Some(stripped) = s.strip_prefix('$') {
72 stripped
73 } else {
74 s
75 };
76 let bytes = hex::decode(hex_str).map_err(|_| "Invalid hex string")?;
77 match bytes.len() {
78 5 => {
79 let mut arr = [0u8; 5];
80 arr.copy_from_slice(&bytes);
81 Ok(PointerAddress::Owned(OwnedPointerAddress::new(arr)))
82 }
83 26 => {
84 let mut arr = [0u8; 26];
85 arr.copy_from_slice(&bytes);
86 Ok(PointerAddress::Referenced(
87 ReferencedPointerAddress::Remote(arr),
88 ))
89 }
90 3 => {
91 let mut arr = [0u8; 3];
92 arr.copy_from_slice(&bytes);
93 Ok(PointerAddress::Referenced(
94 ReferencedPointerAddress::Internal(arr),
95 ))
96 }
97 _ => Err("PointerAddress must be 5, 26 or 3 bytes long"),
98 }
99 }
100}
101
102impl From<RawPointerAddress> for PointerAddress {
103 fn from(raw: RawPointerAddress) -> Self {
104 PointerAddress::from(&raw)
105 }
106}
107
108impl From<&RawLocalPointerAddress> for PointerAddress {
109 fn from(raw: &RawLocalPointerAddress) -> Self {
110 PointerAddress::Owned(OwnedPointerAddress::new(raw.id))
111 }
112}
113
114impl From<&RawInternalPointerAddress> for PointerAddress {
115 fn from(raw: &RawInternalPointerAddress) -> Self {
116 PointerAddress::Referenced(ReferencedPointerAddress::Internal(raw.id))
117 }
118}
119
120impl From<&RawRemotePointerAddress> for PointerAddress {
121 fn from(raw: &RawRemotePointerAddress) -> Self {
122 PointerAddress::Referenced(ReferencedPointerAddress::Remote(raw.id))
123 }
124}
125
126impl From<&RawPointerAddress> for PointerAddress {
127 fn from(raw: &RawPointerAddress) -> Self {
128 match raw {
129 RawPointerAddress::Local(bytes) => {
130 PointerAddress::Owned(OwnedPointerAddress::new(bytes.id))
131 }
132 RawPointerAddress::Internal(bytes) => PointerAddress::Referenced(
133 ReferencedPointerAddress::Internal(bytes.id),
134 ),
135 RawPointerAddress::Remote(bytes) => PointerAddress::Referenced(
136 ReferencedPointerAddress::Remote(bytes.id),
137 ),
138 }
139 }
140}
141
142impl PointerAddress {
143 pub fn to_address_string(&self) -> String {
144 match self {
145 PointerAddress::Owned(local_address) => {
146 hex::encode(local_address.address)
147 }
148 PointerAddress::Referenced(ReferencedPointerAddress::Remote(
149 bytes,
150 )) => hex::encode(bytes),
151 PointerAddress::Referenced(ReferencedPointerAddress::Internal(
152 bytes,
153 )) => hex::encode(bytes),
154 }
155 }
156}
157
158impl Display for PointerAddress {
159 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
160 core::write!(f, "$")?;
161 core::write!(f, "{}", self.to_address_string())
162 }
163}
164impl Serialize for PointerAddress {
165 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
166 where
167 S: serde::Serializer,
168 {
169 let addr_str = self.to_address_string();
170 serializer.serialize_str(&addr_str)
171 }
172}
173impl<'de> Deserialize<'de> for PointerAddress {
174 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
175 where
176 D: serde::Deserializer<'de>,
177 {
178 let s = String::deserialize(deserializer)?;
179 PointerAddress::try_from(s.as_str()).map_err(|e| {
180 serde::de::Error::custom(format!(
181 "Failed to parse PointerAddress: {}",
182 e
183 ))
184 })
185 }
186}
187
188impl PointerAddress {
189 pub fn bytes(&self) -> &[u8] {
190 match self {
191 PointerAddress::Owned(local_address) => &local_address.address,
192 PointerAddress::Referenced(ReferencedPointerAddress::Remote(
193 bytes,
194 )) => bytes,
195 PointerAddress::Referenced(ReferencedPointerAddress::Internal(
196 bytes,
197 )) => bytes,
198 }
199 }
200
201 pub fn internal_bytes(&self) -> Option<&[u8; 3]> {
202 if let PointerAddress::Referenced(ReferencedPointerAddress::Internal(
203 bytes,
204 )) = self
205 {
206 Some(bytes)
207 } else {
208 None
209 }
210 }
211}