tentacli_utils/
lib.rs

1use std::io::{Read, Write};
2use std::num::ParseIntError;
3
4use anyhow::anyhow;
5use flate2::Compression;
6use flate2::read::DeflateDecoder;
7use flate2::read::ZlibDecoder;
8use flate2::write::ZlibEncoder;
9use rand::distr::{Distribution, StandardUniform};
10use rand::Rng;
11
12#[allow(dead_code)]
13pub fn generate_random_number<T>() -> T
14where
15    StandardUniform: Distribution<T>,
16{
17    let mut rng = rand::rng();
18    rng.random::<T>()
19}
20
21#[allow(dead_code)]
22pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
23    let str = s.replace(' ', "");
24    (0..str.len())
25        .step_by(2)
26        .map(|i| u8::from_str_radix(&str[i..i + 2], 16))
27        .collect()
28}
29
30pub fn encode_hex(bytes: &[u8]) -> String {
31    let mut items: Vec<String> = Vec::new();
32    for &b in bytes {
33        items.push(format!("{:02x}", b).to_uppercase());
34    }
35    items.join(" ")
36}
37
38pub fn zlib_decompress(data: &[u8]) -> anyhow::Result<Vec<u8>> {
39    let mut buffer = Vec::new();
40    let mut decoder = ZlibDecoder::new(data);
41    decoder.read_to_end(&mut buffer)?;
42
43    Ok(buffer)
44}
45
46pub fn deflate_decompress(data: &[u8]) -> anyhow::Result<Vec<u8>> {
47    let mut buffer = Vec::new();
48    let mut decoder = DeflateDecoder::new(data);
49    decoder.read_to_end(&mut buffer)?;
50
51    Ok(buffer)
52}
53
54pub fn compress(data: &[u8]) -> anyhow::Result<Vec<u8>> {
55    let mut encoder = ZlibEncoder::new(Vec::new(), Compression::best());
56    encoder.write_all(data)?;
57
58    encoder.finish().map_err(|e| anyhow!("Error on compress: {}", e))
59}
60
61pub fn camel_to_upper_snake_case(name: &str) -> String {
62    let mut result = String::new();
63    let mut previous_was_upper = true;
64
65    for c in name.chars() {
66        if c.is_uppercase() && !previous_was_upper {
67            result.push('_');
68        }
69        result.push(c.to_uppercase().next().unwrap());
70        previous_was_upper = c.is_uppercase() || c.is_numeric();
71    }
72
73    result
74}
75
76#[cfg(test)]
77mod tests {
78    use crate::{compress, decode_hex, encode_hex, zlib_decompress};
79
80    #[test]
81    fn test_decompress() {
82        let origin = vec![1, 2, 3, 4, 5, 6, 7, 8];
83        let compressed = compress(&origin).unwrap();
84
85        assert_eq!(origin, zlib_decompress(&compressed).unwrap());
86    }
87
88    #[test]
89    fn test_encode_decode() {
90        const ORIGIN: [u8; 5] = [255, 12, 3, 45, 5];
91        let encoded = encode_hex(&ORIGIN);
92        assert_eq!("FF 0C 03 2D 05", encoded);
93
94        assert_eq!(ORIGIN.to_vec(), decode_hex(&encoded).unwrap());
95    }
96}