os_checker_types/
prelude.rs1pub 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
12pub 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}