qrbill 0.2.2

A implementation of [qrbill](https://www.swiss-qr-invoice.org/) in Rust
Documentation
#[derive(Debug, Clone)]
pub struct Iso11649 {
    number: String,
}

#[derive(thiserror::Error, Debug)]
pub enum Error {
    #[error("Length must be between 5 and 25.")]
    InvalidLength,
    #[error("Number must start with 'RF'.")]
    InvalidFormat,
    #[error("Checksum is invalid.")]
    InvalidChecksum,
}

impl Iso11649 {
    pub fn try_new(number: String) -> Result<Self, Error> {
        let number = number
            .replace(" ", "")
            .replace("-", "")
            .replace(".", "")
            .replace(",", "")
            .replace("/", "")
            .replace(":", "");
        if number.len() < 5 || number.len() > 25 {
            return Err(Error::InvalidLength);
        }
        if !number.starts_with("RF") {
            return Err(Error::InvalidFormat);
        }

        let valid = format!("{}{}", &number[4..], &number[..4])
            .chars()
            .map(|v| {
                i64::from_str_radix(&v.to_string(), 36).expect("This is a bug. Please rport it.")
            })
            .fold(String::new(), |a, b| format!("{}{}", a, b))
            .parse::<u64>()
            .expect("This is a bug. Please report it.")
            % 97
            == 1;
        if !valid {
            return Err(Error::InvalidChecksum);
        }
        Ok(Self { number })
    }

    pub fn to_raw(&self) -> String {
        self.number.clone()
    }
}

impl ToString for Iso11649 {
    fn to_string(&self) -> String {
        self.number
            .chars()
            .collect::<Vec<char>>()
            .chunks(4)
            .map(|c| c.iter().collect::<String>())
            .collect::<Vec<String>>()
            .join(" ")
    }
}