asteroid_mq_model/
util.rs1use std::fmt::Write;
2
3use bytes::Bytes;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
7pub struct MaybeBase64Bytes(pub Bytes);
8
9impl Serialize for MaybeBase64Bytes {
10 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
11 if serializer.is_human_readable() {
12 use base64::Engine;
13 serializer
14 .serialize_str(&base64::engine::general_purpose::STANDARD.encode(self.0.as_ref()))
15 } else {
16 <Bytes>::serialize(&self.0, serializer)
17 }
18 }
19}
20
21impl<'de> Deserialize<'de> for MaybeBase64Bytes {
22 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
23 if deserializer.is_human_readable() {
24 use base64::Engine;
25 use serde::de::Error;
26 let s = <&'de str>::deserialize(deserializer)?;
27 let bytes = base64::engine::general_purpose::STANDARD
28 .decode(s.as_bytes())
29 .map_err(D::Error::custom)?;
30 Ok(Self(Bytes::from(bytes)))
31 } else {
32 let bytes = Bytes::deserialize(deserializer)?;
33 Ok(Self(bytes))
34 }
35 }
36}
37
38impl MaybeBase64Bytes {
39 pub fn new(bytes: Bytes) -> Self {
40 Self(bytes)
41 }
42 pub fn into_inner(self) -> Bytes {
43 self.0
44 }
45}
46
47pub fn hex<B: AsRef<[u8]> + ?Sized>(bytes: &B) -> Hex<'_> {
48 Hex(bytes.as_ref())
49}
50
51pub struct Hex<'a>(&'a [u8]);
52
53impl std::fmt::Debug for Hex<'_> {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 for byte in self.0 {
56 write!(f, "{:02x}", byte)?;
57 }
58 Ok(())
59 }
60}
61
62impl std::fmt::Display for Hex<'_> {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 for byte in self.0 {
65 write!(f, "{:02x}", byte)?;
66 }
67 Ok(())
68 }
69}
70
71pub fn dashed<I: std::fmt::Debug>(arr: &impl AsRef<[I]>) -> Dashed<'_, I> {
72 Dashed(arr.as_ref())
73}
74
75pub struct Dashed<'a, I>(&'a [I]);
76
77impl<I> std::fmt::Debug for Dashed<'_, I>
78where
79 I: std::fmt::Debug,
80{
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 let size = self.0.len();
83 for (index, i) in self.0.iter().enumerate() {
84 f.write_fmt(format_args!("{:?}", i))?;
85 if index + 1 != size {
86 f.write_char('-')?
87 }
88 }
89 Ok(())
90 }
91}
92
93pub struct MemUnit(pub usize);
94
95impl std::fmt::Display for MemUnit {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 let unit = ["", "B", "KB", "MB", "GB"];
98 let unit_base = [0, 1, 1 << 10, 1 << 20, 1 << 30];
99 let uint_index = unit_base
100 .iter()
101 .position(|&base| self.0 < base)
102 .unwrap_or(unit_base.len())
103 - 1;
104 let uint = unit[uint_index];
105 if self.0 == 0 {
106 write!(f, "0")
107 } else {
108 let value = self.0 as f64 / unit_base[uint_index] as f64;
109 write!(f, "{:.2}{}", value, uint)
110 }
111 }
112}
113pub fn executor_digest() -> u64 {
114 thread_local! {
115 static MACH_ID: std::cell::OnceCell<u64> = const { std::cell::OnceCell::new() };
116 }
117 MACH_ID.with(|t| {
118 *t.get_or_init(|| {
119 let thread = std::thread::current().id();
120 let mach = machine_uid::get()
121 .unwrap_or_else(|_| std::env::var("MACHINE_ID").expect("Cannot get machine id"));
122 let mut hasher = std::hash::DefaultHasher::new();
123 std::hash::Hash::hash(&thread, &mut hasher);
124 std::hash::Hash::hash(&mach, &mut hasher);
125
126 std::hash::Hasher::finish(&hasher)
127 })
128 })
129}
130
131pub fn timestamp_sec() -> u64 {
132 std::time::SystemTime::now()
133 .duration_since(std::time::UNIX_EPOCH)
134 .expect("time never goes backward")
135 .as_secs()
136}