#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))]
#[inline]
#[must_use = "This predicate should be used intentionally in byte-level checks"]
pub const fn is_ascii_printable(byte: u8) -> bool {
byte >= 0x20 && byte <= 0x7E
}
#[inline]
#[must_use = "This predicate should be used intentionally in byte-level checks"]
pub const fn is_likely_corrupted_ebcdic_byte(byte: u8) -> bool {
matches!(byte, 0x00..=0x1F | 0x7F..=0x9F)
}
#[inline]
#[must_use = "This predicate should be used intentionally in packed-decimal checks"]
pub const fn is_invalid_comp3_high_nibble(byte: u8) -> bool {
matches!((byte >> 4) & 0x0F, 0xA | 0xB | 0xE)
}
#[inline]
#[must_use = "This predicate should be used intentionally in packed-decimal checks"]
pub const fn is_invalid_comp3_low_nibble(byte: u8) -> bool {
matches!(byte & 0x0F, 0xA | 0xB | 0xE)
}
#[inline]
#[must_use = "This predicate should be used intentionally in packed-decimal checks"]
pub const fn is_invalid_comp3_sign_nibble(byte: u8) -> bool {
matches!(byte & 0x0F, 0x0..=0x9)
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn ascii_printable_examples() {
assert!(is_ascii_printable(b'A'));
assert!(is_ascii_printable(b' '));
assert!(!is_ascii_printable(0x1F));
}
#[test]
fn ascii_printable_lower_boundary() {
assert!(!is_ascii_printable(0x1F)); assert!(is_ascii_printable(0x20)); }
#[test]
fn ascii_printable_upper_boundary() {
assert!(is_ascii_printable(0x7E)); assert!(!is_ascii_printable(0x7F)); }
#[test]
fn ascii_printable_all_digits() {
for b in b'0'..=b'9' {
assert!(is_ascii_printable(b));
}
}
#[test]
fn ascii_printable_all_uppercase() {
for b in b'A'..=b'Z' {
assert!(is_ascii_printable(b));
}
}
#[test]
fn ascii_printable_null_and_max() {
assert!(!is_ascii_printable(0x00));
assert!(!is_ascii_printable(0xFF));
}
#[test]
fn likely_corrupted_ebcdic_examples() {
assert!(is_likely_corrupted_ebcdic_byte(0x00));
assert!(is_likely_corrupted_ebcdic_byte(0x7F));
assert!(!is_likely_corrupted_ebcdic_byte(b'A'));
assert!(!is_likely_corrupted_ebcdic_byte(0xFF));
}
#[test]
fn ebcdic_c0_range_all_corrupted() {
for b in 0x00..=0x1F {
assert!(
is_likely_corrupted_ebcdic_byte(b),
"byte 0x{b:02X} should be corrupted"
);
}
}
#[test]
fn ebcdic_c1_range_all_corrupted() {
for b in 0x7F..=0x9F {
assert!(
is_likely_corrupted_ebcdic_byte(b),
"byte 0x{b:02X} should be corrupted"
);
}
}
#[test]
fn ebcdic_boundary_0x20_not_corrupted() {
assert!(!is_likely_corrupted_ebcdic_byte(0x20));
}
#[test]
fn ebcdic_boundary_0xa0_not_corrupted() {
assert!(!is_likely_corrupted_ebcdic_byte(0xA0));
}
#[test]
fn ebcdic_high_bytes_not_corrupted() {
assert!(!is_likely_corrupted_ebcdic_byte(0xC1));
assert!(!is_likely_corrupted_ebcdic_byte(0xF0));
}
#[test]
fn comp3_invalid_high_nibble_detection() {
assert!(is_invalid_comp3_high_nibble(0xA2));
assert!(is_invalid_comp3_high_nibble(0xBE));
assert!(!is_invalid_comp3_high_nibble(0x12));
}
#[test]
fn comp3_high_nibble_valid_digits_0_to_9() {
for high in 0..=9u8 {
assert!(
!is_invalid_comp3_high_nibble(high << 4),
"high nibble {high} should be valid"
);
}
}
#[test]
fn comp3_high_nibble_a_b_e_invalid() {
assert!(is_invalid_comp3_high_nibble(0xA0));
assert!(is_invalid_comp3_high_nibble(0xB0));
assert!(is_invalid_comp3_high_nibble(0xE0));
}
#[test]
fn comp3_high_nibble_c_d_f_valid() {
assert!(!is_invalid_comp3_high_nibble(0xC0));
assert!(!is_invalid_comp3_high_nibble(0xD0));
assert!(!is_invalid_comp3_high_nibble(0xF0));
}
#[test]
fn comp3_invalid_low_nibble_detection() {
assert!(is_invalid_comp3_low_nibble(0x0A));
assert!(is_invalid_comp3_low_nibble(0x5B));
assert!(!is_invalid_comp3_low_nibble(0x56));
}
#[test]
fn comp3_low_nibble_valid_digits_0_to_9() {
for low in 0..=9u8 {
assert!(
!is_invalid_comp3_low_nibble(low),
"low nibble {low} should be valid"
);
}
}
#[test]
fn comp3_low_nibble_a_b_e_invalid() {
assert!(is_invalid_comp3_low_nibble(0x0A));
assert!(is_invalid_comp3_low_nibble(0x0B));
assert!(is_invalid_comp3_low_nibble(0x0E));
}
#[test]
fn comp3_low_nibble_c_d_f_valid() {
assert!(!is_invalid_comp3_low_nibble(0x0C));
assert!(!is_invalid_comp3_low_nibble(0x0D));
assert!(!is_invalid_comp3_low_nibble(0x0F));
}
#[test]
fn comp3_invalid_sign_nibble_detection() {
assert!(is_invalid_comp3_sign_nibble(0x12));
assert!(!is_invalid_comp3_sign_nibble(0x1C));
assert!(!is_invalid_comp3_sign_nibble(0x1D));
}
#[test]
fn comp3_sign_nibble_digits_0_to_9_all_invalid() {
for low in 0..=9u8 {
assert!(
is_invalid_comp3_sign_nibble(low),
"sign nibble {low} should be invalid"
);
}
}
#[test]
fn comp3_sign_nibble_c_d_f_all_valid() {
assert!(!is_invalid_comp3_sign_nibble(0x0C)); assert!(!is_invalid_comp3_sign_nibble(0x0D)); assert!(!is_invalid_comp3_sign_nibble(0x0F)); }
#[test]
fn comp3_sign_nibble_a_b_e_also_valid() {
assert!(!is_invalid_comp3_sign_nibble(0x0A));
assert!(!is_invalid_comp3_sign_nibble(0x0B));
assert!(!is_invalid_comp3_sign_nibble(0x0E));
}
}