simple_comms 1.2.2

Rust implementation of a communication protocol for AH
Documentation
pub fn add_padding_with_scheme<F>(data: &[u8], block_size: usize, padding_fn: F) -> Vec<u8>
where
    F: Fn(usize) -> Vec<u8>,
{
    if !(1..=255).contains(&block_size) {
        panic!("Block size must be between 1 and 255 inclusive");
    }
    let padding_len = block_size - (data.len() % block_size);
    let mut padded_data = data.to_vec();
    padded_data.extend(padding_fn(padding_len));
    padded_data
}

pub fn remove_padding_with_scheme<F>(
    padded_data: &[u8],
    block_size: usize,
    validate_fn: F,
) -> Result<Vec<u8>, String>
where
    F: Fn(&[u8]) -> Result<usize, String>,
{
    if padded_data.is_empty() {
        return Err("Data is empty, no padding to remove".to_string());
    }

    let padding_len = validate_fn(&padded_data)?;

    if padding_len > block_size || padding_len > padded_data.len() {
        return Err("Invalid padding length".to_string());
    }

    let actual_data_len = padded_data.len() - padding_len;

    Ok(padded_data[..actual_data_len].to_vec())
}

pub fn pkcs7_padding(padding_len: usize) -> Vec<u8> {
    vec![padding_len as u8; padding_len]
}

pub fn pkcs7_validation(padded: &[u8]) -> Result<usize, String> {
    let padding_len = *padded.last().unwrap() as usize;
    if padding_len == 0 || padding_len > padded.len() {
        return Err("Invalid padding length".to_string());
    }

    if !padded[padded.len() - padding_len..]
        .iter()
        .all(|&byte| byte as usize == padding_len)
    {
        return Err("Invalid padding bytes".to_string());
    }

    Ok(padding_len)
}

pub fn x_padding(padding_len: usize) -> Vec<u8> {
    vec![8; padding_len]
}

pub fn x_trim_validation(padded: &[u8]) -> Result<usize, String> {
    let padding_len = padded.iter().rev().take_while(|&&byte| byte == 8).count();
    Ok(padding_len)
}