1use crate::key::{Action, Key};
4
5#[rustfmt::skip]
7pub const LAYOUT: [[Key; 14]; 4] = {
8 use Key::*;
9 [
10 [Grave, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0, Minus, Equal, Backspace],
11 [Tab, Q, W, E, R, T, Y, U, I, O, P, LeftBracket, RightBracket, Backslash],
12 [Fn, Shift, A, S, D, F, G, H, J, K, L, Semicolon, Quote, Enter],
13 [Ctrl, Opt, Alt, Z, X, C, V, B, N, M, Comma, Period, Slash, Space],
14 ]
15};
16
17pub const ADV_MATRIX_ROWS: u8 = 7;
19pub const ADV_MATRIX_COLS: u8 = 8;
21
22pub const fn from_adv_matrix(row: u8, col: u8) -> Option<Key> {
29 if row >= ADV_MATRIX_ROWS || col >= ADV_MATRIX_COLS {
30 return None;
31 }
32 let phys_col = row * 2 + (col >= 4) as u8;
33 let phys_row = col % 4;
34 Some(LAYOUT[phys_row as usize][phys_col as usize])
35}
36
37pub const fn fn_layer(key: Key) -> Option<Action> {
39 use Key::*;
40 Some(match key {
41 Grave => Action::Escape,
42 Num1 => Action::F(1),
43 Num2 => Action::F(2),
44 Num3 => Action::F(3),
45 Num4 => Action::F(4),
46 Num5 => Action::F(5),
47 Num6 => Action::F(6),
48 Num7 => Action::F(7),
49 Num8 => Action::F(8),
50 Num9 => Action::F(9),
51 Num0 => Action::F(10),
52 Minus => Action::F(11),
53 Equal => Action::F(12),
54 Backspace => Action::Delete,
55 Semicolon => Action::Up,
56 Comma => Action::Left,
57 Period => Action::Down,
58 Slash => Action::Right,
59 _ => return None,
60 })
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn layout_lists_every_key_once_in_discriminant_order() {
69 let flat = LAYOUT.as_flattened();
70 assert_eq!(flat.len(), Key::COUNT);
71 for (i, k) in flat.iter().enumerate() {
72 assert_eq!(*k as usize, i);
73 }
74 }
75
76 #[test]
77 fn adv_matrix_maps_every_key_once() {
78 let mut seen = 0u64;
79 for row in 0..ADV_MATRIX_ROWS {
80 for col in 0..ADV_MATRIX_COLS {
81 let key = from_adv_matrix(row, col).unwrap();
82 assert_eq!(seen & key.bit(), 0, "{key:?} mapped twice");
83 seen |= key.bit();
84 }
85 }
86 assert_eq!(seen.count_ones() as usize, Key::COUNT);
87 assert_eq!(from_adv_matrix(7, 0), None);
88 assert_eq!(from_adv_matrix(0, 8), None);
89
90 assert_eq!(from_adv_matrix(0, 0), Some(Key::Grave));
92 assert_eq!(from_adv_matrix(0, 4), Some(Key::Num1));
93 assert_eq!(from_adv_matrix(0, 3), Some(Key::Ctrl));
94 assert_eq!(from_adv_matrix(6, 7), Some(Key::Space));
95 assert_eq!(from_adv_matrix(6, 6), Some(Key::Enter));
96 }
97}