bin_encode_decode/decode/
func.rs

1use crate::*;
2
3/// decodes a given encoded string based on a specified charset, using 4-character
4/// groups to restore the original bytes. Each character in the `decode_str` string
5/// is mapped to an index in `charset` to form the decoded bytes.
6///
7/// # Parameters
8/// - `charset`: A string representing the character set used to encode and decode
9///   the data. Each character should have a unique position in `charset`.
10/// - `decode_str`: The string to be decoded, which was originally encoded with
11///   the provided `charset`.
12///
13/// # Returns
14/// Returns a `Result` containing the decodeed `String` if successful, or a `DecodeError` if the charset is invalid.
15///
16/// # Example
17/// ```
18/// use bin_encode_decode::*;
19///
20/// let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=";
21/// let encoded_str = "aab0aabLaabZaab0";
22/// let decoded_str = decode(charset, encoded_str);
23/// assert_eq!(decoded_str.unwrap(), "test");
24/// ```
25#[inline]
26pub fn decode(charset: &str, decode_str: &str) -> Result<String, DecodeError> {
27    if !Endecode::judge_charset_safe(charset) {
28        return Err(DecodeError::CharsetError);
29    }
30    let mut buffer: Vec<u8> = Vec::new();
31    let mut decoded: Vec<u8> = Vec::new();
32    for ch in decode_str.chars() {
33        if let Some(idx) = charset.chars().position(|c| c == ch) {
34            buffer.push(idx as u8);
35        }
36        if buffer.len() == 4 {
37            let combined: usize = ((buffer[0] as usize) << 18)
38                | ((buffer[1] as usize) << 12)
39                | ((buffer[2] as usize) << 6)
40                | (buffer[3] as usize);
41            decoded.push((combined >> 16) as u8);
42            decoded.push((combined >> 8) as u8);
43            decoded.push(combined as u8);
44            buffer.clear();
45        }
46    }
47    let decode_res: String =
48        String::from_utf8(decoded.into_iter().filter(|&x| x != 0).collect()).unwrap_or_default();
49    Ok(decode_res)
50}