rs_utilities/
lib.rs

1#[macro_use]
2pub mod macros;
3pub mod cached_value;
4pub mod dns;
5use std::sync::Once;
6
7extern crate pretty_env_logger;
8
9static INIT_LOGGER_ONCE: Once = Once::new();
10
11#[cfg(not(target_os = "android"))]
12macro_rules! colored_log {
13    ($buf:ident, $record:ident, $tag:ident, $term_color:literal, $level:literal) => {{
14        let module = $record.target();
15        writeln!(
16            $buf,
17            concat!($term_color, "{} [{}] [{}:{}] [", $level, "] {}\x1B[0m"),
18            chrono::Local::now().format("%Y-%m-%d %H:%M:%S.%3f"),
19            $tag,
20            module,
21            $record.line().unwrap_or(0),
22            $record.args()
23        )
24    }};
25}
26
27pub struct LogHelper;
28impl LogHelper {
29    pub fn init_logger(tag: &'static str, log_filter: &str) {
30        INIT_LOGGER_ONCE.call_once(|| LogHelper::do_init_logger(tag, log_filter));
31    }
32
33    #[cfg(not(target_os = "android"))]
34    fn do_init_logger(tag: &'static str, log_filter: &str) {
35        use std::io::Write;
36
37        let log_filter = if let Ok(log_filter) = std::env::var("RUST_LOG") {
38            log_filter
39        } else {
40            log_filter.to_string()
41        };
42
43        pretty_env_logger::formatted_timed_builder()
44            .format(move |buf, record| match record.level() {
45                log::Level::Trace => colored_log!(buf, record, tag, "\x1B[0m", "T"),
46                log::Level::Debug => colored_log!(buf, record, tag, "\x1B[92m", "D"),
47                log::Level::Info => colored_log!(buf, record, tag, "\x1B[34m", "I"),
48                log::Level::Warn => colored_log!(buf, record, tag, "\x1B[93m", "W"),
49                log::Level::Error => colored_log!(buf, record, tag, "\x1B[31m", "E"),
50            })
51            .parse_filters(log_filter.as_str())
52            .init();
53    }
54
55    #[cfg(target_os = "android")]
56    fn do_init_logger(tag: &str, log_filter: &str) {
57        let log_filter = if let Ok(log_filter) = std::env::var("RUST_LOG") {
58            log_filter
59        } else {
60            log_filter.to_string()
61        };
62
63        android_logger::init_once(
64            android_logger::Config::default()
65                .with_max_level(log::LevelFilter::Trace)
66                .with_tag(tag)
67                .with_filter(
68                    android_logger::FilterBuilder::new()
69                        .parse(log_filter.as_str())
70                        .build(),
71                ),
72        );
73    }
74}
75
76pub struct Utils;
77
78impl Utils {
79    pub fn to_u32_be(array: &[u8]) -> u32 {
80        if array.len() < 4 {
81            panic!("array length is less than 4");
82        }
83        ((array[0] as u32) << 24)
84            + ((array[1] as u32) << 16)
85            + ((array[2] as u32) << 8)
86            + ((array[3] as u32) << 0)
87    }
88
89    pub fn to_u32_le(array: &[u8]) -> u32 {
90        if array.len() < 4 {
91            panic!("array length is less than 4");
92        }
93        ((array[0] as u32) << 0)
94            + ((array[1] as u32) << 8)
95            + ((array[2] as u32) << 16)
96            + ((array[3] as u32) << 24)
97    }
98
99    pub fn as_u32_be(n: u32, array: &mut [u8]) {
100        if array.len() < 4 {
101            panic!("array length is less than 4");
102        }
103        array[0] = ((n >> 24) & 0xff) as u8;
104        array[1] = ((n >> 16) & 0xff) as u8;
105        array[2] = ((n >> 8) & 0xff) as u8;
106        array[3] = (n & 0xff) as u8;
107    }
108
109    pub fn as_u32_le(n: u32, array: &mut [u8]) {
110        if array.len() < 4 {
111            panic!("array length is less than 4");
112        }
113        array[0] = (n & 0xff) as u8;
114        array[1] = ((n >> 8) & 0xff) as u8;
115        array[2] = ((n >> 16) & 0xff) as u8;
116        array[3] = ((n >> 24) & 0xff) as u8;
117    }
118
119    pub fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
120        let min_len = std::cmp::min(dst.len(), src.len());
121        dst[..min_len].copy_from_slice(&src[..min_len]);
122        min_len
123    }
124}
125
126pub struct ByteBuffer<const N: usize> {
127    arr: [u8; N],
128    used: usize,
129}
130
131impl<const N: usize> ByteBuffer<N> {
132    pub fn new() -> Self {
133        ByteBuffer {
134            arr: [0u8; N],
135            used: 0,
136        }
137    }
138
139    pub fn as_bytes(&self) -> &[u8] {
140        &self.arr[..self.used]
141    }
142
143    /// return false if remaining buffer is not big enough to store the data
144    pub fn append(&mut self, data: &[u8]) -> bool {
145        if data.len() + self.used > N {
146            return false;
147        }
148        Utils::copy_slice(&mut self.arr[self.used..], data);
149        self.used += data.len();
150        true
151    }
152
153    pub fn append_byte(&mut self, byte: u8) -> bool {
154        if 1 + self.used > N {
155            return false;
156        }
157        self.arr[self.used] = byte;
158        self.used += 1;
159        true
160    }
161
162    pub fn clear(&mut self) {
163        self.used = 0;
164    }
165
166    pub const fn remaining(&self) -> usize {
167        N - self.used
168    }
169
170    pub const fn len(&self) -> usize {
171        self.used
172    }
173
174    pub const fn capacity(&self) -> usize {
175        N
176    }
177}
178
179#[cfg(test)]
180
181mod tests {
182    use crate::{LogHelper, Utils};
183
184    #[test]
185    fn it_works() {
186        LogHelper::init_logger("haha", "rs_utilities=trace");
187        log::trace!("test trace");
188        log::debug!("test debug");
189        log::info!("test info");
190        log::warn!("test warn");
191        log::error!("test error");
192
193        let mut arr1 = [0u8; 1024];
194        arr1[3] = 1;
195
196        assert_eq!(Utils::to_u32_be(&[0, 0, 0, 1]), 1);
197        assert_eq!(Utils::to_u32_le(&[0, 0, 0, 1]), 16777216);
198        assert_eq!(Utils::to_u32_be(&arr1[..4]), 1);
199
200        let mut arr2 = [0u8; 1024];
201        let n = 0x12345678;
202        Utils::as_u32_be(n, &mut arr2);
203        assert_eq!(Utils::to_u32_be(&arr2[..4]), n);
204        assert_eq!(Utils::to_u32_le(&arr2[..4]), 0x78563412);
205    }
206}