os_checker_types/
prelude.rs

1pub use camino::{Utf8Path, Utf8PathBuf};
2pub use compact_str::CompactString as XString;
3pub use eyre::Result;
4pub use indexmap::IndexMap;
5pub use musli::{Decode, Encode};
6pub use serde::{Deserialize, Serialize};
7pub use std::fmt;
8
9use std::{fmt::Debug, hash::Hash};
10use time::OffsetDateTime;
11
12/// Returns the current unix timestamp in milliseconds.
13pub fn now() -> u64 {
14    let t = time::OffsetDateTime::from(std::time::SystemTime::now());
15    unix_timestamp_milli(t)
16}
17
18pub fn unix_timestamp_milli(t: OffsetDateTime) -> u64 {
19    let milli = t.millisecond() as u64;
20    let unix_t_secs = t.unix_timestamp() as u64;
21    unix_t_secs * 1000 + milli
22}
23
24pub fn parse_unix_timestamp_milli(ts: u64) -> OffsetDateTime {
25    let t_with_millis = ts / 1000;
26    match OffsetDateTime::from_unix_timestamp((t_with_millis) as i64) {
27        Ok(t) => t
28            .replace_millisecond((ts - t_with_millis * 1000) as u16)
29            .unwrap()
30            .to_offset(time::UtcOffset::from_hms(8, 0, 0).unwrap()),
31        Err(err) => panic!("{ts} 无法转回时间:{err}"),
32    }
33}
34
35#[macro_export]
36macro_rules! redb_value {
37    (
38      $t:ident, name: $name:literal,
39      read_err: $read_err:literal, write_err: $write_err:literal
40    ) => {
41        impl ::redb::Value for $t {
42            type SelfType<'a>
43                = Self
44            where
45                Self: 'a;
46
47            type AsBytes<'a>
48                = Vec<u8>
49            where
50                Self: 'a;
51
52            fn fixed_width() -> Option<usize> {
53                None
54            }
55
56            fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
57            where
58                Self: 'a,
59            {
60                use std::error::Error;
61                match ::musli::storage::from_slice(data) {
62                    Ok(res) => res,
63                    Err(err) => {
64                        panic!(
65                            "{}\nerr (debug) = {err:?}\nerr (display) = {err}\nerr (source) = {:?}",
66                            $read_err, err.source()
67                        )
68                    }
69                }
70            }
71
72            fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
73            where
74                Self: 'a,
75                Self: 'b,
76            {
77                ::musli::storage::to_vec(value).expect($write_err)
78            }
79
80            fn type_name() -> redb::TypeName {
81                ::redb::TypeName::new($name)
82            }
83        }
84    };
85    (@key
86      $t:ident, name: $name:literal,
87      read_err: $read_err:literal, write_err: $write_err:literal
88    ) => {
89        redb_value!($t, name: $name, read_err: $read_err, write_err: $write_err);
90        impl ::redb::Key for $t {
91            fn compare(data1: &[u8], data2: &[u8]) -> ::std::cmp::Ordering {
92                data1.cmp(data2)
93            }
94        }
95    };
96}
97
98fn count_key<K: Hash + Eq + Debug>(k: K, map: &mut IndexMap<K, u8>) {
99    if let Some(count) = map.get_mut(&k) {
100        error!(key = ?k, "The occurrence shouldn't be more than 1.");
101        *count += 1;
102    } else {
103        map.insert(k, 1);
104    }
105}
106
107pub fn check_key_uniqueness<K: Hash + Eq + Debug>(
108    iter: impl ExactSizeIterator<Item = K>,
109) -> Result<()> {
110    let mut count = IndexMap::with_capacity(iter.len());
111    iter.for_each(|k| count_key(k, &mut count));
112    let invalid: Vec<_> = count.iter().filter(|(_, c)| **c != 1u8).collect();
113    ensure!(invalid.is_empty(), "invalid = {invalid:#?}");
114    Ok(())
115}