base_d/
alphabet.rs

1use std::collections::HashMap;
2use crate::config::EncodingMode;
3
4#[derive(Debug, Clone)]
5pub struct Alphabet {
6    chars: Vec<char>,
7    char_to_index: HashMap<char, usize>,
8    mode: EncodingMode,
9    padding: Option<char>,
10}
11
12impl Alphabet {
13    pub fn new(chars: Vec<char>) -> Result<Self, String> {
14        Self::new_with_mode(chars, EncodingMode::BaseConversion, None)
15    }
16    
17    pub fn new_with_mode(chars: Vec<char>, mode: EncodingMode, padding: Option<char>) -> Result<Self, String> {
18        if chars.is_empty() {
19            return Err("Alphabet cannot be empty".to_string());
20        }
21        
22        // Validate alphabet size for chunked mode
23        if mode == EncodingMode::Chunked {
24            let base = chars.len();
25            if !base.is_power_of_two() {
26                return Err(format!("Chunked mode requires power-of-two alphabet size, got {}", base));
27            }
28        }
29        
30        let mut char_to_index = HashMap::new();
31        for (i, &c) in chars.iter().enumerate() {
32            if char_to_index.insert(c, i).is_some() {
33                return Err(format!("Duplicate character in alphabet: {}", c));
34            }
35        }
36        
37        Ok(Alphabet {
38            chars,
39            char_to_index,
40            mode,
41            padding,
42        })
43    }
44    
45    pub fn from_str(s: &str) -> Result<Self, String> {
46        let chars: Vec<char> = s.chars().collect();
47        Self::new(chars)
48    }
49    
50    pub fn base(&self) -> usize {
51        self.chars.len()
52    }
53    
54    pub fn mode(&self) -> &EncodingMode {
55        &self.mode
56    }
57    
58    pub fn padding(&self) -> Option<char> {
59        self.padding
60    }
61    
62    pub fn encode_digit(&self, digit: usize) -> Option<char> {
63        self.chars.get(digit).copied()
64    }
65    
66    pub fn decode_char(&self, c: char) -> Option<usize> {
67        self.char_to_index.get(&c).copied()
68    }
69}
70
71