asteroid_mq_model/
util.rs

1use 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}