use crate::{ Based, BasedError, Alphabet, AlphabetError };
#[derive(Default)]
pub struct BasedBuilder {
val: String,
base: usize,
alphabet: Alphabet,
}
impl BasedBuilder {
pub fn new(val: String) -> Self {
Self {
val,
base: 10,
alphabet: Alphabet::Default,
}
}
pub fn val<T: Into<String>>(self, val: T) -> Self {
Self {
val: val.into(),
base: self.base,
alphabet: self.alphabet,
}
}
pub fn base(self, base: usize) -> Self {
Self {
val: self.val,
base,
alphabet: self.alphabet,
}
}
pub fn alphabet<T: Into<Alphabet>>(self, abc: T) -> Self {
Self {
val: self.val,
base: self.base,
alphabet: abc.into(),
}
}
pub fn check(self) -> Result<Self, BasedError> {
if self.base == 0 {
return Err( BasedError::BaseZero )
}
for c in self.val.chars() {
let char_val = self.alphabet.chars_index(c).unwrap();
let abc_len = self.alphabet.get().len();
if char_val > self.base - 1 {
return Err( AlphabetError::TooHighValue(c).into() )
}
if char_val > abc_len {
return Err( AlphabetError::TooSmallAlphabet(char_val - abc_len).into() )
}
}
Ok(self)
}
pub fn is_valid(&self) -> bool {
if self.base == 0 {
return false
}
for c in self.val.chars() {
let char_val = self.alphabet.chars_index(c).unwrap();
let abc_len = self.alphabet.get().len();
if char_val > self.base - 1 || char_val > abc_len{
return false
}
}
true
}
pub fn build(self) -> Based {
let num = self.check().unwrap();
Based {
val: num.val,
base: num.base,
alphabet: num.alphabet,
}
}
pub fn build_unchecked(self) -> Based {
Based {
val: self.val,
base: self.base,
alphabet: self.alphabet,
}
}
}