polymer 0.2.0

Modular keyboard firmware.
use keebrs::{
    keycode::KeyCode::*,
    translate::{
        Action::{
            self,
            *,
        },
        Layout,
        Map,
        Module,
        Orientation,
    },
};

const TILDE: Action = Combo(&[KbLShift, KbGrave]);
const USCORE: Action = Combo(&[KbLShift, KbHyphen]);
const PLUS: Action = Combo(&[KbLShift, KbEq]);
const BANG: Action = Combo(&[KbLShift, Kb1]);
const AT: Action = Combo(&[KbLShift, Kb2]);
const HASH: Action = Combo(&[KbLShift, Kb3]);
const DOLLAR: Action = Combo(&[KbLShift, Kb4]);
const PERCENT: Action = Combo(&[KbLShift, Kb5]);
const CARAT: Action = Combo(&[KbLShift, Kb6]);
const AMP: Action = Combo(&[KbLShift, Kb7]);
const STAR: Action = Combo(&[KbLShift, Kb8]);
const LPAREN: Action = Combo(&[KbLShift, Kb9]);
const RPAREN: Action = Combo(&[KbLShift, Kb0]);
const RBRACK: Action = Combo(&[KbLShift, KbLBrace]);
const LBRACK: Action = Combo(&[KbLShift, KbRBrace]);

const START_UNICODE: Action = Combo(&[KbLShift, KbLCtrl, KbU]);

macro_rules! unicode {
    ($($e:expr),*) => {
        Seq(&[START_UNICODE, $(Key($e)),* , Key(KbEnter)])
    };
}

const SHRUG_HAND: Action = Seq(&[START_UNICODE, Key(KbA), Key(KbF), Key(KbEnter)]);

const SHRUG_FACE: Action = unicode!(Kb3, Kb0, KbC, Kb4);

const SHRUGGIE: Action = Seq(&[
    SHRUG_HAND,
    Key(KbBackSlash),
    USCORE,
    LPAREN,
    SHRUG_FACE,
    RPAREN,
    USCORE,
    Key(KbSlash),
    SHRUG_HAND,
]);

const TABLE_FLIP: Action = Seq(&[
    LPAREN,
    unicode!(Kb2, Kb5, Kb1, KbB),
    unicode!(KbC, KbA, Kb0),
    USCORE,
    unicode!(KbC, KbA, Kb0),
    RPAREN,
    unicode!(Kb2, Kb5, Kb1, KbB),
    unicode!(Kb5, KbF, Kb6, Kb1),
    unicode!(Kb2, Kb5, Kb3, KbB),
    unicode!(Kb2, Kb5, Kb0, Kb1),
    unicode!(Kb2, Kb5, Kb3, KbB),
]);

fn bootloader() {
    // At worst, this'll just reboot the board if the bkp isn't enabled
    unsafe {
        crate::reboot::reboot_bootloader(core::mem::transmute(()));
    }
}

#[rustfmt::skip]
const LEFT_0: Map = Map(&[
    &[Key(KbIns),      Key(KbGrave),  Key(Kb1),    Key(Kb2),     Key(Kb3),    Key(Kb4), Key(Kb5)    ],
    &[Key(KbHyphen),   Key(KbTab),    Key(KbQ),    Key(KbW),     Key(KbE),    Key(KbR), Key(KbT)    ],
    &[Key(KbEq),       Key(KbEscape), Key(KbA),    Key(KbS),     Key(KbD),    Key(KbF), Key(KbG)    ],
    &[Key(KbPageUp),   Key(KbLShift), Key(KbZ),    Key(KbX),     Key(KbC),    Key(KbV), Key(KbB)    ],
    &[Key(KbPageDown), Key(KbLCtrl),  Key(KbLGui), Layer(3),     Key(KbLAlt), Layer(2), Key(KbSpace)],
]);

#[rustfmt::skip]
const RIGHT_0: Map = Map(&[
    &[Key(Kb6),     Key(Kb7), Key(Kb8),       Key(Kb9),       Key(Kb0),     Key(KbBackspace), Key(KbDelete)],
    &[Key(KbY),     Key(KbU), Key(KbI),       Key(KbO),       Key(KbP),     Key(KbLBrace),    Key(KbRBrace)],
    &[Key(KbH),     Key(KbJ), Key(KbK),       Key(KbL),       Key(KbSemi),  Key(KbQuote),     Key(KbEnter) ],
    &[Key(KbN),     Key(KbM), Key(KbComma),   Key(KbPeriod),  Key(KbSlash), Key(KbBackSlash), Key(KbHome)  ],
    &[Key(KbSpace), Layer(1), Key(KbLeftArr), Key(KbDownArr), Key(KbUpArr), Key(KbRightArr),  Key(KbEnd)   ],
]);

#[rustfmt::skip]
const LEFT_1: Map = Map(&[
    &[Nop,      TILDE,          Key(KbF1),         Key(KbF2),       Key(KbF3),      Key(KbF4),  Key(KbF5) ],
    &[USCORE,   Nop,            BANG,              AT,              HASH,           DOLLAR,     PERCENT   ],
    &[PLUS,     Nop,            Key(KbF1),         Key(KbF2),       Key(KbF3),      Key(KbF4),  Key(KbF5) ],
    &[Nop,      Trans,          Key(KbF7),         Key(KbF8),       Key(KbF9),      Key(KbF10), Key(KbF11)],
    &[Layer(3), Key(MediaNext), Key(MediaVolDown), Key(MediaVolUp), Key(MediaPlay), Trans,      Trans     ],
]);

#[rustfmt::skip]
const RIGHT_1: Map = Map(&[
    &[Key(KbF6),  Key(KbF7), Key(KbF8),      Key(KbF9),         Key(KbF10),      Key(KbF11),      Key(KbF12)],
    &[CARAT,      AMP,       STAR,           LPAREN,            RPAREN,          LBRACK,          RBRACK    ],
    &[Key(KbF6),  USCORE,    PLUS,           LBRACK,            RBRACK,          Nop,             Nop       ],
    &[Key(KbF12), Nop,       Nop,            Nop,               Nop,             Nop,             Nop       ],
    &[Trans,      Trans,     Key(MediaNext), Key(MediaVolDown), Key(MediaVolUp), Key(MediaPlay),  Layer(3)  ],
]);

#[rustfmt::skip]
const LEFT_2: Map = Map(&[
    &[Nop,      TILDE,          Key(KbF1),         Key(KbF2),       Key(KbF3),      Key(KbF4),  Key(KbF5) ],
    &[USCORE,   Nop,            Key(Kb1),          Key(Kb2),        Key(Kb3),       Key(Kb4),   Key(Kb5)  ],
    &[PLUS,     Nop,            Key(KbF1),         Key(KbF2),       Key(KbF3),      Key(KbF4),  Key(KbF5) ],
    &[Nop,      Trans,          Key(KbF7),         Key(KbF8),       Key(KbF9),      Key(KbF10), Key(KbF11)],
    &[Layer(3), Key(MediaNext), Key(MediaVolDown), Key(MediaVolUp), Key(MediaPlay), Trans,      Trans     ],
]);

#[rustfmt::skip]
const RIGHT_2: Map = Map(&[
    &[Key(KbF6),  Key(KbF7),     Key(KbF8),      Key(KbF9),         Key(KbF10),      Key(KbF11),     Key(KbF12)],
    &[Key(Kb6),   Key(Kb7),      Key(Kb8),       Key(Kb9),          Key(Kb0),        LBRACK,         RBRACK    ],
    &[Key(KbF6),  Key(KbHyphen), Key(KbEq),      Key(KbLBrace),     Key(KbRBrace),   Nop,            Nop       ],
    &[Key(KbF12), Nop,           Nop,            Nop,               Nop,             Nop,            Nop       ],
    &[Trans,      Trans,         Key(MediaNext), Key(MediaVolDown), Key(MediaVolUp), Key(MediaPlay), Layer(3)  ],
]);

#[rustfmt::skip]
const LEFT_3: Map = Map(&[
    &[Nop,   Nop,   Nop,   Nop,      Nop,     Nop, Fn(bootloader)],
    &[Nop,   Nop,   Nop,   Nop,      Nop,     Nop, TABLE_FLIP    ],
    &[Nop,   Nop,   Nop,   SHRUGGIE, Nop,     Nop, Nop           ],
    &[Nop,   Trans, Nop,   Nop,      Nop,     Nop, Nop           ],
    &[Trans, Trans, Trans, Trans,    Trans,   Nop, Nop           ],
]);

#[rustfmt::skip]
const RIGHT_3: Map = Map(&[
    &[Fn(bootloader), Nop, Nop, Nop, Nop, Nop, Nop  ],
    &[Nop,            Nop, Nop, Nop, Nop, Nop, Nop  ],
    &[Nop,            Nop, Nop, Nop, Nop, Nop, Nop  ],
    &[Nop,            Nop, Nop, Nop, Nop, Nop, Nop  ],
    &[Nop,            Nop, Nop, Nop, Nop, Nop, Trans],
]);

const LEFT: Module = Module {
    ty: "ortho5x7",
    layers: &[LEFT_0, LEFT_1, LEFT_2, LEFT_3],
    orientation: Orientation::RC,
};

const RIGHT: Module = Module {
    ty: "ortho5x7",
    layers: &[RIGHT_0, RIGHT_1, RIGHT_2, RIGHT_3],
    orientation: Orientation::RC,
};

#[rustfmt::skip]
const DEBUG_ALL: Map = Map(&[
    &[Nop, Nop, Nop, Nop, Nop, Nop, Nop],
    &[Nop, Nop, Nop, Nop, Nop, Nop, Nop],
    &[Nop, Nop, Nop, Nop, Nop, Nop, Nop],
    &[Nop, Nop, Nop, Nop, Nop, Nop, Nop],
    &[Nop, Nop, Nop, Nop, Nop, Nop, Nop],
]);

const DEBUG: Module = Module {
    ty: "debug",
    layers: &[DEBUG_ALL, DEBUG_ALL, DEBUG_ALL, DEBUG_ALL],
    orientation: Orientation::RC,
};

pub const LAYOUT: Layout = Layout {
    modules: &[LEFT, DEBUG, RIGHT],
};