emv-qrcps 0.1.1

Features a non-alloc deserializer, and a serializer for any specification based on EMV-QrCode.
Documentation
use std::borrow::Cow;

use crc::{Algorithm, Crc, CRC_16_IBM_3740};

pub(crate) const CRC_ALGO: Algorithm<u16> = CRC_16_IBM_3740;

pub fn calculate_crc16(complete_pix: &str) -> u16 {
    let crc = Crc::<u16>::new(&CRC_ALGO);
    let mut digest = crc.digest();

    digest.update(complete_pix.as_bytes());
    digest.finalize()
}

pub fn finalize() {
    todo!()
}

pub fn validate(key: &str) -> bool {
    let total_size = key.len() - 4;
    let source_key_crc = &key[total_size..];

    let check = u16::from_str_radix(source_key_crc, 16).unwrap();
    let checked_string_without_crc = &key[..total_size];

    let crc = Crc::<u16>::new(&CRC_ALGO);
    let mut digest = crc.digest();

    digest.update(checked_string_without_crc.as_bytes());
    let final_crc = digest.finalize();
    check == final_crc
}

pub trait Encode {
    fn encode(&self) -> String;
}

pub trait Size {
    fn char_count(&self) -> i32;
}

impl Size for i32 {
    fn char_count(&self) -> i32 {
        ((*self as f32).log10() + 1.0).floor() as i32
    }
}

impl Size for &str {
    fn char_count(&self) -> i32 {
        self.len() as i32
    }
}

impl Size for Cow<'_, str> {
    fn char_count(&self) -> i32 {
        self.len() as i32
    }
}

impl Size for &Cow<'_, str> {
    fn char_count(&self) -> i32 {
        self.len() as i32
    }
}

impl Size for String {
    fn char_count(&self) -> i32 {
        self.len() as i32
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn bacen_static_sample() -> &'static str {
        "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-4266554400005204000053039865802BR5913Fulano de \
         Tal6008BRASILIA62070503***63041D3D"
    }

    #[test]
    fn t_calculate_crc() {
        let sample = bacen_static_sample();
        let sample_size = bacen_static_sample().len();
        assert_eq!(format!("{:X}", calculate_crc16(&sample[..sample_size - 4])), "1D3D")
    }

    #[test]
    fn char_count_str() {
        let slice = "abcd";
        assert_eq!(4, slice.char_count());
    }

    #[test]
    fn char_count_numeric() {
        let number = 999;
        assert_eq!(3, number.char_count());
    }
}