fast_able/
num_log.rs

1use std::{time::Duration, usize};
2
3pub type LogStr = arraystring::SmallString;
4
5#[derive(Debug, Clone, Copy, PartialEq)]
6pub enum NumLog {
7    None,
8    S(&'static str),
9    I(i64),
10    F(f64),
11    Str(LogStr),
12    Dur(Duration),
13    Time(chrono::NaiveTime),
14}
15
16impl NumLog {
17    pub fn is_numeric(&self) -> bool {
18        match self {
19            NumLog::None => false,
20            NumLog::S(_) => false,
21            NumLog::I(_) => true,
22            NumLog::F(_) => true,
23            NumLog::Str(_) => false,
24            NumLog::Dur(_) => true,
25            NumLog::Time(_) => true,
26        }
27    }
28}
29
30impl Default for NumLog {
31    fn default() -> Self {
32        NumLog::None
33    }
34}
35
36impl std::fmt::Display for NumLog {
37    fn fmt(&self, format: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        match self {
39            NumLog::None => write!(format, ""),
40            NumLog::S(s) => write!(format, "{s}"),
41            NumLog::I(i) => write!(format, "{i}"),
42            NumLog::F(f) => write!(format, "{f:.2}"),
43            NumLog::Str(s) => write!(format, "{s}"),
44            NumLog::Dur(s) => write!(format, "{s:?}"),
45            NumLog::Time(b) => write!(format, "{}", b.format("%H:%M:%S%.6f")),
46        }
47    }
48}
49
50#[derive(Debug, Clone, Copy)]
51pub struct NumLogs<const L: usize> {
52    title: &'static str,
53    num_log: [NumLog; L],
54    index: usize,
55}
56
57impl<const L: usize> NumLogs<L> {
58    pub fn new(title: &'static str) -> Self {
59        let r = [Default::default(); L];
60        return Self {
61            title,
62            num_log: r,
63            index: 0,
64        };
65    }
66
67    pub fn get_title(&self) -> &'static str {
68        self.title
69    }
70
71    pub fn is_empty(&self) -> bool {
72        self.index == 0
73    }
74
75    pub fn len(&self) -> usize {
76        self.index
77    }
78
79    pub fn clear(&mut self) {
80        self.index = 0;
81    }
82
83    #[inline(always)]
84    pub fn add(&mut self, n: impl IntoNumLog) -> &mut Self {
85        let n = n.into_num_log();
86        if self.index >= L {
87            #[cfg(debug_assertions)]
88            eprintln!("NumLogs is full({} >= {}): {n}", self.index, L);
89
90            self.index += 1;
91            return self;
92        }
93        self.num_log[self.index] = n;
94        self.index += 1;
95        self
96    }
97
98    #[inline(always)]
99    pub fn push(&mut self, s: (&'static str, String)) -> &mut Self {
100        self.add(s.0).add(s.1)
101    }
102
103    #[inline(always)]
104    pub fn push_arr(&mut self, arr: Vec<(&'static str, String)>) -> &mut Self {
105        for ele in arr {
106            self.push(ele);
107        }
108        self
109    }
110
111    #[inline(always)]
112    pub fn add2(&mut self, n: impl IntoNumLog, n2: impl IntoNumLog) -> &mut Self {
113        self.add(n).add(n2)
114    }
115
116    #[inline(always)]
117    pub fn add_whitespace(&mut self) -> &mut Self {
118        self.add(", ")
119    }
120
121    #[inline(always)]
122    pub fn add_k(&mut self) -> &mut Self {
123        self.add(": ")
124    }
125
126    #[inline(always)]
127    pub fn add_arr<const ARR_LEN: usize, T: IntoNumLog>(
128        &mut self,
129        s_arr: [T; ARR_LEN],
130    ) -> &mut Self {
131        for ele in s_arr {
132            let ele = ele.into_num_log();
133            self.add(ele);
134        }
135        self
136    }
137
138    #[inline(always)]
139    pub fn add_vec<T: IntoNumLog>(&mut self, s_arr: Vec<T>) -> &mut Self {
140        for ele in s_arr {
141            let ele = ele.into_num_log();
142            self.add(ele);
143        }
144        self
145    }
146
147    #[inline(always)]
148    pub fn append<const LEN: usize>(&mut self, vals: NumLogs<LEN>) -> &mut Self {
149        let mut i = vals.index;
150        for ele in vals.num_log {
151            self.add(ele);
152            i -= 1;
153            if i == 0 {
154                break;
155            }
156        }
157        self
158    }
159}
160
161pub trait IntoNumLog {
162    fn into_num_log(self) -> NumLog;
163}
164
165impl IntoNumLog for NumLog {
166    fn into_num_log(self) -> NumLog {
167        self
168    }
169}
170
171impl IntoNumLog for &'static str {
172    fn into_num_log(self) -> NumLog {
173        NumLog::S(self)
174    }
175}
176
177impl IntoNumLog for String {
178    fn into_num_log(self) -> NumLog {
179        NumLog::Str(self.as_str().into())
180    }
181}
182
183impl IntoNumLog for i32 {
184    fn into_num_log(self) -> NumLog {
185        NumLog::I(self as i64)
186    }
187}
188
189impl IntoNumLog for i64 {
190    fn into_num_log(self) -> NumLog {
191        NumLog::I(self)
192    }
193}
194
195impl IntoNumLog for usize {
196    fn into_num_log(self) -> NumLog {
197        NumLog::I(self as i64)
198    }
199}
200
201impl IntoNumLog for u32 {
202    fn into_num_log(self) -> NumLog {
203        NumLog::I(self as i64)
204    }
205}
206
207impl IntoNumLog for u64 {
208    fn into_num_log(self) -> NumLog {
209        NumLog::I(self as i64)
210    }
211}
212
213impl IntoNumLog for f32 {
214    fn into_num_log(self) -> NumLog {
215        NumLog::F(self as f64)
216    }
217}
218
219impl IntoNumLog for f64 {
220    fn into_num_log(self) -> NumLog {
221        NumLog::F(self)
222    }
223}
224
225impl IntoNumLog for Duration {
226    fn into_num_log(self) -> NumLog {
227        NumLog::Dur(self)
228    }
229}
230
231impl IntoNumLog for chrono::Duration {
232    fn into_num_log(self) -> NumLog {
233        NumLog::Dur(self.to_std().unwrap_or_else(|_| Duration::ZERO))
234    }
235}
236
237impl IntoNumLog for chrono::NaiveDateTime {
238    fn into_num_log(self) -> NumLog {
239        NumLog::Time(self.time())
240    }
241}
242
243impl IntoNumLog for chrono::NaiveDate {
244    fn into_num_log(self) -> NumLog {
245        self.format("%Y-%m-%d").to_string().into_num_log()
246    }
247}
248
249impl IntoNumLog for chrono::NaiveTime {
250    fn into_num_log(self) -> NumLog {
251        NumLog::Time(self)
252    }
253}
254
255impl<const L: usize> std::fmt::Display for NumLogs<L> {
256    fn fmt(&self, format: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
257        let mut s = String::new();
258        for i in 0..self.index {
259            if i == L {
260                break;
261            }
262            let v = &self.num_log[i];
263            s.push_str(&v.to_string());
264            if v.is_numeric() {
265                s.push_str(", ");
266            }
267        }
268        write!(format, "{}", s.trim_end_matches(", "))?;
269        Ok(())
270    }
271}
272
273pub trait NumTrait {
274    fn num(self) -> i64;
275}
276
277impl NumTrait for i64 {
278    fn num(self) -> i64 {
279        self
280    }
281}
282
283impl NumTrait for i128 {
284    fn num(self) -> i64 {
285        self as i64
286    }
287}
288
289impl NumTrait for i32 {
290    fn num(self) -> i64 {
291        self as i64
292    }
293}
294
295impl NumTrait for usize {
296    fn num(self) -> i64 {
297        self as i64
298    }
299}
300
301#[test]
302fn test() {
303    let s = LogStr::from("123456789");
304    println!(
305        "num_logs 123456789 size_of_val: {}",
306        std::mem::size_of_val(&s)
307    );
308    println!("LogStr: {s}");
309
310    let s = LogStr::from("一二三四五六七八九");
311    println!(
312        "num_logs 一二三四五六七八九 size_of_val: {}",
313        std::mem::size_of_val(&s)
314    );
315    println!("LogStr: {s}");
316
317    let time = std::time::Instant::now();
318    let mut num_logs = NumLogs::<32>::new("test log");
319    println!("num_logs::new() elapsed: {:?}", time.elapsed());
320
321    println!("num_logs size_of_val: {}", std::mem::size_of_val(&num_logs));
322    num_logs
323        .add("is a ")
324        .add("string; ")
325        .add(1)
326        .add(2)
327        .add(3)
328        .add("floatVal: ")
329        .add(123.45678)
330        .add(2222.0)
331        .add("int64Val: ")
332        .add(3333_i64)
333        .add(4444_i32)
334        .add("字符串数组: ".to_string())
335        .add_arr([5555, 66666, 7777])
336        .add2("时间: ", chrono::Local::now().naive_local())
337        .add2("时间-date: ", chrono::Local::now().naive_local().date())
338        .add_whitespace()
339        .add2("时间-time: ", chrono::Local::now().naive_local().time())
340        .add_arr([5555, 66666, 7777])
341        .add2("耗时: ", time.elapsed())
342        .add(8888);
343    println!("num_logs: {}", num_logs);
344
345    let mut num_logs = NumLogs::<10>::new("test log: ");
346    for i in 1..=9 {
347        num_logs.add(i);
348    }
349    println!("num_logs<10>: {}", num_logs);
350
351    let mut num_logs = NumLogs::<10>::new("test log: ");
352    num_logs.add2("num1:", 1);
353    num_logs.add2("num2:", 2);
354    num_logs.add("num3");
355    println!("num_logs<5>: {}", num_logs);
356
357    let mut num_logs2 = NumLogs::<20>::new("test log: ");
358    for i in 1..=10 {
359        num_logs2.add(i);
360    }
361    num_logs2.append(num_logs);
362    num_logs2.add("; end");
363    println!("num_logs2: {}", num_logs2);
364}