rqjs_ext/modules/encoding/
encoder.rs1use hex_simd::AsciiCase;
4
5macro_rules! encoder_enum {
6 (
7 $(#[$attr:meta])*
8 pub enum $enum_name:ident {
9 $($variant:ident),* $(,)?
10 }
11 ) => {
12 $(#[$attr])*
13 pub enum $enum_name {
14 $($variant),*
15 }
16
17 impl $enum_name {
18 #[allow(clippy::should_implement_trait)]
19 pub fn from_str(encoding: &str) -> Result<Self, String> {
20
21 let encoding:String = encoding.chars()
22 .enumerate()
23 .map(|(i, c)| {
24 if i == 0 {
25 c.to_ascii_uppercase()
26 } else {
27 c.to_ascii_lowercase()
28 }
29 })
30 .filter(|&c| c != '-' && c != '_')
31 .collect();
32
33 match encoding.as_str() {
34 $(
35 stringify!($variant) => Ok(Self::$variant),
36 )*
37 _ => Err(format!("Unsupported encoding: {}", encoding)),
38 }
39 }
40 }
41 };
42}
43
44encoder_enum! {
45 #[derive(Debug)]
46 pub enum Encoder {
47 Hex,
48 Base64,
49 Utf8,
50 Iso88591,
51 }
52}
53
54impl Encoder {
55 pub fn encode_to_string(&self, bytes: &[u8]) -> Result<String, String> {
56 match self {
57 Self::Hex => Ok(bytes_to_hex_string(bytes)),
58 Self::Base64 => Ok(bytes_to_b64_string(bytes)),
59 Self::Utf8 | Self::Iso88591 => Ok(bytes_to_string(bytes)),
60 }
61 }
62
63 #[allow(dead_code)]
64 pub fn encode(&self, bytes: &[u8]) -> Result<Vec<u8>, String> {
65 match self {
66 Self::Hex => Ok(bytes_to_hex(bytes)),
67 Self::Base64 => Ok(bytes_to_b64(bytes)),
68 Self::Utf8 | Self::Iso88591 => Ok(bytes.to_vec()),
69 }
70 }
71
72 pub fn decode(&self, bytes: Vec<u8>) -> Result<Vec<u8>, String> {
73 match self {
74 Self::Hex => bytes_from_hex(&bytes),
75 Self::Base64 => bytes_from_b64(&bytes),
76 Self::Utf8 | Self::Iso88591 => Ok(bytes),
77 }
78 }
79
80 #[allow(dead_code)]
81 pub fn decode_from_string(&self, string: String) -> Result<Vec<u8>, String> {
82 match self {
83 Self::Hex => bytes_from_hex(string.as_bytes()),
84 Self::Base64 => bytes_from_b64(string.as_bytes()),
85 Self::Utf8 | Self::Iso88591 => Ok(string.into_bytes()),
86 }
87 }
88}
89
90pub fn bytes_to_hex(bytes: &[u8]) -> Vec<u8> {
91 hex_simd::encode_type(bytes, AsciiCase::Lower)
92}
93
94pub fn bytes_from_hex(hex_bytes: &[u8]) -> Result<Vec<u8>, String> {
95 hex_simd::decode_to_vec(hex_bytes).map_err(|err| err.to_string())
96}
97
98pub fn bytes_to_b64_string(bytes: &[u8]) -> String {
99 base64_simd::STANDARD.encode_to_string(bytes)
100}
101
102pub fn bytes_from_b64(bytes: &[u8]) -> Result<Vec<u8>, String> {
103 base64_simd::forgiving_decode_to_vec(bytes).map_err(|e| e.to_string())
104}
105
106pub fn bytes_to_b64(bytes: &[u8]) -> Vec<u8> {
107 base64_simd::STANDARD.encode_type(bytes)
108}
109
110pub fn bytes_to_hex_string(bytes: &[u8]) -> String {
111 hex_simd::encode_to_string(bytes, AsciiCase::Lower)
112}
113
114pub fn bytes_to_string(bytes: &[u8]) -> String {
115 String::from_utf8_lossy(bytes).to_string()
116}