1use crate::constants::{DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH};
16use crate::{Error, ErrorKind, Result};
17use std::fmt::{self, Display, Formatter};
18
19#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Hash)]
21pub struct DestinationAddressBytes([u8; DESTINATION_ADDRESS_LENGTH]);
22
23impl DestinationAddressBytes {
24 pub fn as_base58_string(&self) -> String {
25 bs58::encode(&self.0).into_string()
26 }
27
28 pub fn try_from_base58_string<S: Into<String>>(val: S) -> Result<Self> {
29 let decoded = match bs58::decode(val.into()).into_vec() {
30 Ok(decoded) => decoded,
31 Err(e) => {
32 return Err(Error::new(
33 ErrorKind::InvalidRouting,
34 format!("failed to decode destination from b58 string: {:?}", e),
35 ))
36 }
37 };
38
39 if decoded.len() != DESTINATION_ADDRESS_LENGTH {
40 return Err(Error::new(
41 ErrorKind::InvalidRouting,
42 "decoded destination address has invalid length",
43 ));
44 }
45
46 let mut address_bytes = [0; DESTINATION_ADDRESS_LENGTH];
47 address_bytes.copy_from_slice(&decoded[..]);
48
49 Ok(DestinationAddressBytes(address_bytes))
50 }
51
52 pub fn from_bytes(b: [u8; DESTINATION_ADDRESS_LENGTH]) -> Self {
53 DestinationAddressBytes(b)
54 }
55
56 pub fn try_from_byte_slice(b: &[u8]) -> Result<Self> {
57 if b.len() != DESTINATION_ADDRESS_LENGTH {
58 return Err(Error::new(
59 ErrorKind::InvalidRouting,
60 "received bytes got invalid length",
61 ));
62 }
63
64 let mut address_bytes = [0; DESTINATION_ADDRESS_LENGTH];
65 address_bytes.copy_from_slice(b);
66
67 Ok(DestinationAddressBytes(address_bytes))
68 }
69
70 pub fn as_bytes_ref(&self) -> &[u8; DESTINATION_ADDRESS_LENGTH] {
72 &self.0
73 }
74
75 pub fn as_bytes(&self) -> [u8; DESTINATION_ADDRESS_LENGTH] {
77 self.0
78 }
79}
80
81impl Display for DestinationAddressBytes {
82 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
83 self.as_base58_string().fmt(f)
84 }
85}
86
87#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Hash)]
89pub struct NodeAddressBytes([u8; NODE_ADDRESS_LENGTH]);
90
91impl NodeAddressBytes {
92 pub fn as_base58_string(&self) -> String {
93 bs58::encode(&self.0).into_string()
94 }
95
96 pub fn try_from_base58_string<S: Into<String>>(val: S) -> Result<Self> {
97 let decoded = match bs58::decode(val.into()).into_vec() {
98 Ok(decoded) => decoded,
99 Err(e) => {
100 return Err(Error::new(
101 ErrorKind::InvalidRouting,
102 format!("failed to decode node address from b58 string: {:?}", e),
103 ))
104 }
105 };
106
107 if decoded.len() != NODE_ADDRESS_LENGTH {
108 return Err(Error::new(
109 ErrorKind::InvalidRouting,
110 "decoded node address has invalid length",
111 ));
112 }
113
114 let mut address_bytes = [0; NODE_ADDRESS_LENGTH];
115 address_bytes.copy_from_slice(&decoded[..]);
116
117 Ok(NodeAddressBytes(address_bytes))
118 }
119
120 pub fn try_from_byte_slice(b: &[u8]) -> Result<Self> {
121 if b.len() != NODE_ADDRESS_LENGTH {
122 return Err(Error::new(
123 ErrorKind::InvalidRouting,
124 "received bytes got invalid length",
125 ));
126 }
127
128 let mut address_bytes = [0; NODE_ADDRESS_LENGTH];
129 address_bytes.copy_from_slice(b);
130
131 Ok(NodeAddressBytes(address_bytes))
132 }
133
134 pub fn from_bytes(b: [u8; NODE_ADDRESS_LENGTH]) -> Self {
135 NodeAddressBytes(b)
136 }
137
138 pub fn as_bytes(&self) -> &[u8; NODE_ADDRESS_LENGTH] {
140 &self.0
141 }
142
143 pub fn to_bytes(&self) -> [u8; NODE_ADDRESS_LENGTH] {
145 self.0
146 }
147}
148
149impl Display for NodeAddressBytes {
150 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
151 self.as_base58_string().fmt(f)
152 }
153}
154
155pub type SURBIdentifier = [u8; IDENTIFIER_LENGTH];
157
158#[derive(Clone, Debug, PartialEq, Eq)]
159pub struct Destination {
160 pub address: DestinationAddressBytes,
163 pub identifier: SURBIdentifier,
164}
165
166impl Destination {
167 pub fn new(address: DestinationAddressBytes, identifier: SURBIdentifier) -> Self {
168 Self {
169 address,
170 identifier,
171 }
172 }
173}
174
175#[derive(Clone, Debug)]
176pub struct Node {
177 pub address: NodeAddressBytes,
178 pub pub_key: x25519_dalek::PublicKey,
179}
180
181impl Node {
182 pub fn new(address: NodeAddressBytes, pub_key: x25519_dalek::PublicKey) -> Self {
183 Self { address, pub_key }
184 }
185}
186
187#[cfg(test)]
188mod address_encoding {
189 use super::*;
190
191 #[test]
192 fn it_is_possible_to_encode_and_decode_address() {
193 let dummy_address = NodeAddressBytes([42u8; 32]);
194 let dummy_address_str = dummy_address.as_base58_string();
195 let recovered = NodeAddressBytes::try_from_base58_string(dummy_address_str).unwrap();
196 assert_eq!(dummy_address, recovered)
197 }
198}