num_base 0.4.2

Crate for manipulating with numbers (integers) in different bases.
Documentation
use crate::{ Based, BasedError, Alphabet, AlphabetError };

#[derive(Default)]
/// Builder for `Based` number.
pub struct BasedBuilder {
    val: String,
    base: usize,
    alphabet: Alphabet,
}

impl BasedBuilder {
    /// Creates new `BasedBuilder` with base 10.
    pub fn new(val: String) -> Self {
        Self {
            val,
            base: 10,
            alphabet: Alphabet::Default,
        }
    }

    /// Changes `BasedBuilder`'s value.
    pub fn val<T: Into<String>>(self, val: T) -> Self {
        Self {
            val: val.into(),
            base: self.base,
            alphabet: self.alphabet,
        }
    }

    /// Changes `BasedBuilder`'s base.
    pub fn base(self, base: usize) -> Self {
        Self {
            val: self.val,
            base,
            alphabet: self.alphabet,
        }
    }

    /// Changes `BasedBuilder`'s alphabet.
    pub fn alphabet<T: Into<Alphabet>>(self, abc: T) -> Self {
        Self {
            val: self.val,
            base: self.base,
            alphabet: abc.into(),
        }
    }

    /// Checks for:
    /// - characters (in `val`) with higher value than `base`,
    /// - characters with undefined value,
    /// - Base 0.
    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)
    }

    /// Checks for:
    /// - characters (in `val`) with higher value than `base`,
    /// - characters with undefined value,
    /// - Base 0.
    ///
    /// Use [`check()`](Self::check()) to get error info.
    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
    }

    /// Builds a `Based` number.
    pub fn build(self) -> Based {
        let num = self.check().unwrap();

        Based {
            val: num.val,
            base: num.base,
            alphabet: num.alphabet,
        }
    }

    /// Builds a `Based` number.
    /// 
    /// **See: [check()](Self::check()) or [is_valid()](Self::is_valid())**.
    pub fn build_unchecked(self) -> Based {
        Based {
            val: self.val,
            base: self.base,
            alphabet: self.alphabet,
        }
    }
}