keyboard-codes 0.1.0

Cross-platform keyboard key code mapping and conversion
Documentation
//! Utility functions and helpers

use crate::types::Platform;

/// Check if a key code is valid for the given platform
///
/// This is a basic validation that checks if the code is within
/// a reasonable range for the platform.
pub fn is_valid_key_code(code: usize, platform: Platform) -> bool {
    match platform {
        Platform::Windows => code <= 0xFF, // Windows uses 8-bit key codes
        Platform::Linux => code <= 0x2FF,  // Linux uses wider range (up to 767 decimal)
        Platform::MacOS => code <= 0x7F,   // macOS uses 7-bit key codes
    }
}

/// Normalize a key code by masking out any extraneous bits
///
/// Some platforms may have additional bits set in key codes
/// that are not part of the core key code value.
pub fn normalize_key_code(code: usize, platform: Platform) -> usize {
    match platform {
        Platform::Windows => code & 0xFF, // Mask to 8 bits
        Platform::Linux => code & 0x3FF,  // Mask to 10 bits (Linux scancodes can go up to 0x2FF)
        Platform::MacOS => code & 0x7F,   // Mask to 7 bits
    }
}

/// Check if a string is a valid key name
///
/// Valid key names are alphanumeric and start with a letter.
pub fn is_valid_key_name(name: &str) -> bool {
    if name.is_empty() {
        return false;
    }

    // First character must be a letter
    if !name.chars().next().unwrap().is_ascii_alphabetic() {
        return false;
    }

    // All characters must be alphanumeric
    name.chars().all(|c| c.is_ascii_alphanumeric())
}

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

    #[test]
    fn test_is_valid_key_code() {
        assert!(is_valid_key_code(0x41, Platform::Windows));
        assert!(is_valid_key_code(0x100, Platform::Linux));
        assert!(!is_valid_key_code(0x100, Platform::Windows));
    }

    #[test]
    fn test_normalize_key_code() {
        // Windows: mask to 8 bits
        assert_eq!(normalize_key_code(0x141, Platform::Windows), 0x41);
        assert_eq!(normalize_key_code(0x1FF, Platform::Windows), 0xFF);

        // Linux: mask to 10 bits (0x3FF = 1023 decimal)
        assert_eq!(normalize_key_code(0x341, Platform::Linux), 0x341); // 0x341 = 833 decimal
        assert_eq!(normalize_key_code(0x7FF, Platform::Linux), 0x3FF); // Should be masked to max

        // macOS: mask to 7 bits
        assert_eq!(normalize_key_code(0x81, Platform::MacOS), 0x01);
        assert_eq!(normalize_key_code(0xFF, Platform::MacOS), 0x7F);
    }

    #[test]
    fn test_is_valid_key_name() {
        assert!(is_valid_key_name("A"));
        assert!(is_valid_key_name("Enter"));
        assert!(is_valid_key_name("F12"));
        assert!(!is_valid_key_name(""));
        assert!(!is_valid_key_name("123"));
        assert!(!is_valid_key_name("Key-Name"));
    }
}