tgbr_core/
util.rs

1use serde::{Deserialize, Serialize};
2
3macro_rules! trait_alias {
4    (pub trait $name:ident = $($traits:tt)+) => {
5        pub trait $name: $($traits)* {}
6        impl<T: $($traits)*> $name for T {}
7    };
8}
9
10pub(crate) use trait_alias;
11
12#[derive(Default, Serialize, Deserialize)]
13pub struct ClockDivider {
14    count: u64,
15    period: u64,
16}
17
18impl ClockDivider {
19    pub fn new() -> Self {
20        Self {
21            count: 0,
22            period: 0,
23        }
24    }
25
26    pub fn with_period(period: u64) -> Self {
27        Self { count: 0, period }
28    }
29
30    pub fn reset(&mut self) {
31        self.count = 0;
32    }
33
34    pub fn set_period(&mut self, period: u64) {
35        self.count = 0;
36        self.period = period;
37    }
38
39    pub fn tick(&mut self) -> bool {
40        self.count += 1;
41        if self.count >= self.period {
42            self.count = 0;
43            true
44        } else {
45            false
46        }
47    }
48}
49
50pub struct ConstEval<const V: u8>;
51
52impl<const V: u8> ConstEval<V> {
53    pub const VALUE: u8 = V;
54}
55
56macro_rules! pack {
57    (@packing $view:ident $x:literal..=$y:literal => $v:expr $(, $($rest:tt)*)?) => {
58        $view[$x..=$y].store($v);
59        pack!(@packing $view $($($rest)*)*);
60    };
61    (@packing $view:ident $x:literal => $v:expr $(, $($rest:tt)*)?) => {
62        $view.set($x, $v);
63        pack!(@packing $view $($($rest)*)*);
64    };
65    (@packing $view:ident $(,)?) => {};
66    (@packing $($rest:tt)*) => {
67        compile_error!("Invalid input for macro pack!");
68    };
69    ($($input:tt)*) => {{
70        use bitvec::prelude::*;
71        let mut data = 0;
72        let view = data.view_bits_mut::<bitvec::prelude::Lsb0>();
73        pack!(@packing view $($input)*);
74        data
75    }};
76}
77
78pub(crate) use pack;
79
80#[test]
81fn test_pack() {
82    let v: u8 = pack! {
83        0..=2 => 0b101_u8,
84        3 => true,
85        4..=6 => 0b100_u8
86    };
87    assert_eq!(v, 0b01001101);
88}
89
90pub fn to_si_bytesize(x: u64) -> String {
91    bytesize::ByteSize(x).to_string_as(true)
92}