bin_encode_decode/decode/
impl.rs

1use crate::*;
2
3impl Decode {
4    /// decodes a given encoded string based on a specified charset, using 4-character
5    /// groups to restore the original bytes. Each character in the `decode_str` string
6    /// is mapped to an index in `charset` to form the decoded bytes.
7    ///
8    /// # Parameters
9    /// - `charset`: A string representing the character set used to encode and decode
10    ///   the data. Each character should have a unique position in `charset`.
11    /// - `decode_str`: The string to be decoded, which was originally encoded with
12    ///   the provided `charset`.
13    ///
14    /// # Returns
15    /// Returns a `Result` containing the decoded `String` if successful, or a `DecodeError` if the charset is invalid.
16    ///
17    /// # Example
18    /// ```
19    /// use bin_encode_decode::*;
20    ///
21    /// let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=";
22    /// let encoded_str = "aab0aabLaabZaab0";
23    /// let decoded_str = Decode::execute(charset, encoded_str);
24    /// assert_eq!(decoded_str.unwrap(), "test");
25    /// ```
26    pub fn execute(charset: &str, decode_str: &str) -> Result<String, DecodeError> {
27        if !Charset::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())
49                .unwrap_or_default();
50        Ok(decode_res)
51    }
52}