asteroid_mq_model/
endpoint.rs1use serde::{Deserialize, Serialize};
2
3use typeshare::typeshare;
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
6#[typeshare(serialized_as = "String")]
7#[cfg_attr(feature = "bincode", derive(bincode::Decode, bincode::Encode))]
8pub struct EndpointAddr {
9 pub bytes: [u8; 16],
10}
11
12impl From<[u8; 16]> for EndpointAddr {
13 fn from(bytes: [u8; 16]) -> Self {
14 Self { bytes }
15 }
16}
17impl From<EndpointAddr> for [u8; 16] {
18 fn from(val: EndpointAddr) -> Self {
19 val.bytes
20 }
21}
22
23impl Serialize for EndpointAddr {
24 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
25 if serializer.is_human_readable() {
26 use base64::Engine;
27 serializer.serialize_str(&base64::engine::general_purpose::URL_SAFE.encode(self.bytes))
28 } else {
29 <[u8; 16]>::serialize(&self.bytes, serializer)
30 }
31 }
32}
33
34impl<'de> Deserialize<'de> for EndpointAddr {
35 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
36 if deserializer.is_human_readable() {
37 use base64::Engine;
38 use serde::de::Error;
39 let s = String::deserialize(deserializer)?;
40 let bytes = base64::engine::general_purpose::URL_SAFE
41 .decode(s.as_bytes())
42 .map_err(D::Error::custom)?;
43 if bytes.len() != 16 {
44 return Err(D::Error::custom("invalid length"));
45 }
46 let mut addr = [0; 16];
47 addr.copy_from_slice(&bytes);
48 Ok(Self { bytes: addr })
49 } else {
50 let bytes = <[u8; 16]>::deserialize(deserializer)?;
51 Ok(Self { bytes })
52 }
53 }
54}
55
56impl std::fmt::Debug for EndpointAddr {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 f.debug_tuple("EndpointAddr")
59 .field(&crate::util::dashed(&[
60 crate::util::hex(&self.bytes[0..8]),
61 crate::util::hex(&self.bytes[8..12]),
62 crate::util::hex(&self.bytes[12..16]),
63 ]))
64 .finish()
65 }
66}
67
68impl EndpointAddr {
69 pub fn new_snowflake() -> Self {
70 thread_local! {
71 static COUNTER: std::cell::Cell<u32> = const { std::cell::Cell::new(0) };
72 }
73 let timestamp = crate::util::timestamp_sec();
74 let counter = COUNTER.with(|c| {
75 let v = c.get();
76 c.set(v.wrapping_add(1));
77 v
78 });
79 let eid = crate::util::executor_digest() as u32;
80 let mut bytes = [0; 16];
81 bytes[0..8].copy_from_slice(×tamp.to_be_bytes());
82 bytes[8..12].copy_from_slice(&counter.to_be_bytes());
83 bytes[12..16].copy_from_slice(&eid.to_be_bytes());
84 Self { bytes }
85 }
86 pub fn hash64(&self) -> u64 {
87 use std::hash::{DefaultHasher, Hasher};
88 let mut hasher = DefaultHasher::new();
89 Hasher::write(&mut hasher, &self.bytes);
90 Hasher::finish(&hasher)
91 }
92}