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 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}