rxing 0.8.2

A rust port of the zxing barcode library.
Documentation
use crate::common::Result;
use crate::Exceptions;

pub fn calculate_checksum(contents: &str) -> char {
    let sum: u32 = contents.chars().map(|c| c as u32).sum();

    let remainder = sum % 127;
    let diff = 127 - remainder;
    if diff != 127 {
        diff as u8 as char
    } else {
        0 as char
    }
}

pub fn ascii_to_numeric(contents: &str) -> String {
    let mut number = String::with_capacity(contents.chars().count() * 2);

    for c in contents.chars().map(|x| x as u32) {
        if c >= 27 {
            number.push_str(&format!("{:0>2}", (c - 27)));
        } else {
            number.push_str(&format!("{:0>2}", (c - 17)));
        }
    }

    number
}

pub fn numeric_to_ascii(contents: &str) -> Result<String> {
    if contents.len() % 2 != 0 {
        return Err(Exceptions::illegal_argument_with(
            "Input must contain an even number of characters.",
        ));
    }

    let mut ascii = Vec::with_capacity(contents.chars().count() / 2);
    let mut i = 0;

    let cached_contents = contents.chars().map(|c| c as u8).collect::<Vec<_>>();

    while i < cached_contents.len() {
        let first = *cached_contents.get(i).unwrap();
        let second = *cached_contents.get(i + 1).unwrap();

        if second == 88 && (48..=57).contains(&first) {
            ascii.push((17 + first - 48) as char);
        } else if (48..=57).contains(&second) && (48..=57).contains(&first) {
            ascii.push((27 + (first - 48) * 10 + (second - 48)) as char);
        } else {
            return Err(Exceptions::illegal_argument_with(format!(
                "Input contains an invalid character around position {i}."
            )));
        }

        i += 2;
    }

    Ok(ascii.iter().collect())
}

#[test]
fn telepen_checksum_test1() {
    let contents = "Hello world!";
    let checksum = calculate_checksum(contents);
    assert_eq!('\u{1a}', checksum);
}

#[test]
fn telepen_checksum_test2() {
    let contents = "ABC123456";
    let checksum = calculate_checksum(contents);
    assert_eq!('\u{1}', checksum);
}

#[test]
fn telepen_alpha_to_numeric_test() {
    let mut ascii = "'=Siu";
    let mut result = ascii_to_numeric(ascii);
    assert_eq!("1234567890", result);

    ascii = "& oe";
    result = ascii_to_numeric(ascii);
    assert_eq!("11058474", result);
}

#[test]
fn telepen_numeric_to_ascii_test() {
    let mut numeric = "1234567890";
    let mut result = numeric_to_ascii(numeric).unwrap();
    assert_eq!("'=Siu", result);

    numeric = "11058474";
    result = numeric_to_ascii(numeric).unwrap();
    assert_eq!("& oe", result);
}