1use crate::compat::rand::{distributions::Standard, prelude::Distribution, random, Rng};
2use crate::compat::{
3 string::{String, ToString},
4 vec::Vec,
5};
6use crate::{
7 serialize, AddressParseError, AddressParseErrorKind, Encodable, Encoded, Result, TransportType,
8 LOCAL,
9};
10use core::fmt::{self, Debug, Display};
11use core::ops::Deref;
12use core::str::from_utf8;
13use minicbor::{CborLen, Decode, Encode};
14use serde::{Deserialize, Serialize};
15
16#[derive(
36 Serialize, Deserialize, Encode, Decode, CborLen, Clone, Hash, Ord, PartialOrd, Eq, PartialEq,
37)]
38#[rustfmt::skip]
39pub struct Address {
40 #[n(0)] tt: TransportType,
41 #[cbor(with = "minicbor::bytes")]
43 #[n(1)] inner: Vec<u8>,
44}
45
46impl AsRef<Address> for Address {
47 fn as_ref(&self) -> &Address {
48 self
49 }
50}
51
52impl Encodable for Address {
53 fn encode(self) -> Result<Encoded> {
54 serialize(self)
55 }
56}
57
58impl Address {
59 pub fn new_with_string(tt: TransportType, data: impl Into<String>) -> Self {
70 Self {
71 tt,
72 inner: data.into().as_bytes().to_vec(),
73 }
74 }
75
76 pub fn new(tt: TransportType, inner: Vec<u8>) -> Self {
78 Self { tt, inner }
79 }
80
81 pub fn from_string<S: Into<String>>(s: S) -> Self {
98 s.into()
100 .parse::<Address>()
101 .unwrap_or_else(|e| panic!("Invalid address string {e}"))
102 }
103
104 #[doc(hidden)]
106 pub fn without_type(&self) -> &str {
107 from_utf8(&self.inner).unwrap_or("<unprintable>")
108 }
109
110 pub fn random(tt: TransportType) -> Self {
120 Self { tt, ..random() }
121 }
122
123 pub fn random_local() -> Self {
125 Self {
126 tt: LOCAL,
127 ..random()
128 }
129 }
130
131 pub fn random_tagged(_tag: &str) -> Self {
134 #[cfg(feature = "debugger")]
135 {
136 use core::sync::atomic::{AtomicU32, Ordering};
137 static COUNTER: AtomicU32 = AtomicU32::new(0);
138 let address = format!("{}_{}", _tag, COUNTER.fetch_add(1, Ordering::Relaxed),).into();
139 let address = Self {
140 tt: LOCAL,
141 ..address
142 };
143 tracing::trace!("random_tagged => {}", address);
144 address
145 }
146
147 #[cfg(not(feature = "debugger"))]
148 Self::random_local()
149 }
150
151 pub fn transport_type(&self) -> TransportType {
153 self.tt
154 }
155
156 pub fn address(&self) -> &str {
158 from_utf8(self.inner.as_slice()).unwrap_or("Invalid UTF-8")
159 }
160
161 pub fn is_local(&self) -> bool {
163 self.tt == LOCAL
164 }
165
166 pub fn inner(self) -> Vec<u8> {
168 self.inner
169 }
170}
171
172impl core::str::FromStr for Address {
173 type Err = AddressParseError;
174 fn from_str(s: &str) -> Result<Address, Self::Err> {
178 let buf: String = s.into();
179 let mut vec: Vec<_> = buf.split('#').collect();
180
181 if vec.len() == 1 {
184 Ok(Address {
185 tt: LOCAL,
186 inner: vec.remove(0).as_bytes().to_vec(),
187 })
188 }
189 else if vec.len() == 2 {
192 match str::parse(vec.remove(0)) {
193 Ok(tt) => Ok(Address {
194 tt: TransportType::new(tt),
195 inner: vec.remove(0).as_bytes().to_vec(),
196 }),
197 Err(e) => Err(AddressParseError::new(AddressParseErrorKind::InvalidType(
198 e,
199 ))),
200 }
201 } else {
202 Err(AddressParseError::new(AddressParseErrorKind::MultipleSep))
203 }
204 }
205}
206
207impl Display for Address {
208 fn fmt<'a>(&'a self, f: &mut fmt::Formatter) -> fmt::Result {
209 let inner: &'a str = from_utf8(self.inner.as_slice()).unwrap_or("Invalid UTF-8");
210 write!(f, "{}#{}", self.tt, inner)
211 }
212}
213
214impl Debug for Address {
215 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
216 <Self as Display>::fmt(self, f)
217 }
218}
219
220impl Deref for Address {
221 type Target = Vec<u8>;
222 fn deref(&self) -> &Self::Target {
223 &self.inner
224 }
225}
226
227impl From<String> for Address {
228 fn from(s: String) -> Self {
229 Self::from_string(s)
230 }
231}
232
233impl From<&String> for Address {
234 fn from(s: &String) -> Self {
235 Self::from_string(s.as_str())
236 }
237}
238
239impl<'a> From<&'a str> for Address {
240 fn from(s: &'a str) -> Self {
241 Self::from_string(s)
242 }
243}
244
245impl From<Vec<u8>> for Address {
246 fn from(data: Vec<u8>) -> Self {
247 Self {
248 tt: LOCAL,
249 inner: data,
250 }
251 }
252}
253
254impl From<(TransportType, Vec<u8>)> for Address {
255 fn from((tt, data): (TransportType, Vec<u8>)) -> Self {
256 Self { tt, inner: data }
257 }
258}
259
260impl<'a> From<(TransportType, &'a str)> for Address {
261 fn from((tt, data): (TransportType, &'a str)) -> Self {
262 Self {
263 tt,
264 inner: data.as_bytes().to_vec(),
265 }
266 }
267}
268
269impl<'a> From<(TransportType, &'a String)> for Address {
270 fn from((tt, inner): (TransportType, &'a String)) -> Self {
271 Self::from((tt, inner.as_str()))
272 }
273}
274
275impl From<(TransportType, String)> for Address {
276 fn from((transport, data): (TransportType, String)) -> Self {
277 Self::from((transport, data.as_str()))
278 }
279}
280
281impl<'a> From<&'a [u8]> for Address {
282 fn from(data: &'a [u8]) -> Self {
283 Self {
284 tt: LOCAL,
285 inner: data.to_vec(),
286 }
287 }
288}
289
290impl<'a> From<&'a [&u8]> for Address {
291 fn from(data: &'a [&u8]) -> Self {
292 Self {
293 tt: LOCAL,
294 inner: data.iter().map(|x| **x).collect(),
295 }
296 }
297}
298
299impl From<Address> for String {
300 fn from(address: Address) -> Self {
301 address.to_string()
302 }
303}
304
305impl Distribution<Address> for Standard {
306 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Address {
307 let address: [u8; 16] = rng.gen();
308 hex::encode(address).as_bytes().into()
309 }
310}
311
312impl Address {
313 pub(crate) fn manual_encode(&self, buffer: &mut Vec<u8>) {
314 buffer.push(self.tt.into());
315 crate::bare::write_slice(buffer, &self.inner);
316 }
317
318 pub(crate) fn encoded_size(&self) -> usize {
319 1 + crate::bare::size_of_slice(&self.inner)
320 }
321 pub(crate) fn manually_decode(slice: &[u8], index: &mut usize) -> Option<Address> {
322 if slice.len() - *index < 2 {
323 return None;
324 }
325 let tt = slice[*index];
326 *index += 1;
327
328 let inner = crate::bare::read_slice(slice, index)?;
329 Some(Address {
330 tt: TransportType::new(tt),
331 inner: inner.to_vec(),
332 })
333 }
334}
335
336#[cfg(test)]
337mod test {
338 use super::*;
339 use crate::Encodable;
340
341 #[test]
342 fn encode_and_manually_decode_address() {
343 let super_long_string = "a".repeat(250);
344 let address = Address::from_string("42#".to_string() + &super_long_string);
345 assert_eq!(address.address(), super_long_string.as_str());
346
347 let encoded = address.clone().encode().unwrap();
348 let decoded = Address::manually_decode(&encoded, &mut 0).unwrap();
349 assert_eq!(address, decoded);
350 }
351
352 #[test]
353 fn parse_addr_simple() {
354 let addr = Address::from_string("local_friend");
355 assert_eq!(
356 addr,
357 Address {
358 tt: LOCAL,
359 inner: "local_friend".as_bytes().to_vec(),
360 }
361 );
362 }
363
364 #[test]
365 fn parse_addr_with_type() {
366 let addr = Address::from_string("1#remote_friend");
367 assert_eq!(
368 addr,
369 Address {
370 tt: TransportType::new(1),
371 inner: "remote_friend".as_bytes().to_vec(),
372 }
373 );
374 }
375
376 #[test]
377 #[should_panic(expected = "Failed to parse address type:")]
378 fn parse_addr_invalid() {
379 Address::from_string("#,my_friend");
380 }
381
382 #[test]
383 #[should_panic(expected = "Invalid address string:")]
384 fn parse_addr_invalid_multiple_separators() {
385 let _ = Address::from_string("1#invalid#");
386 }
387}