use std::collections::HashMap;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use rmk_config::resolved::behavior::MorseProfile;
use rmk_config::resolved::{Behavior, Keymap};
use super::action_parser::parse_key;
pub(crate) fn expand_default_keymap(keymap: &Keymap, behavior: &Behavior) -> TokenStream2 {
let profiles: Option<HashMap<String, MorseProfile>> = behavior
.morse
.as_ref()
.map(|m| m.profiles.clone())
.filter(|p| !p.is_empty());
let num_encoder = keymap.num_encoder;
let mut layers = vec![];
let mut encoder_map = vec![];
for layer in &keymap.keymap {
layers.push(expand_layer(layer.clone(), &profiles));
}
for encoder_layer in &keymap.encoder_map {
encoder_map.push(expand_encoder_layer(
encoder_layer.clone(),
num_encoder,
&profiles,
));
}
encoder_map.resize(
keymap.keymap.len(),
quote! { [::rmk::encoder!(::rmk::k!(No), ::rmk::k!(No)); NUM_ENCODER] },
);
quote! {
pub const fn get_default_keymap() -> [[[::rmk::types::action::KeyAction; COL]; ROW]; NUM_LAYER] {
[#(#layers), *]
}
pub const fn get_default_encoder_map() -> [[::rmk::types::action::EncoderAction; NUM_ENCODER]; NUM_LAYER] {
[#(#encoder_map), *]
}
}
}
pub(crate) fn expand_layer(
layer: Vec<Vec<String>>,
profiles: &Option<HashMap<String, MorseProfile>>,
) -> TokenStream2 {
let mut rows = vec![];
for row in layer {
rows.push(expand_row(row, profiles));
}
quote! { [#(#rows), *] }
}
fn expand_row(row: Vec<String>, profiles: &Option<HashMap<String, MorseProfile>>) -> TokenStream2 {
let mut keys = vec![];
for key in row {
keys.push(parse_key(key, profiles));
}
quote! { [#(#keys), *] }
}
pub(crate) fn expand_encoder_layer(
encoder_layer: Vec<[String; 2]>,
num_encoder: usize,
profiles: &Option<HashMap<String, MorseProfile>>,
) -> TokenStream2 {
let mut encoders = vec![];
for encoder in encoder_layer {
let cw_action = parse_key(encoder[0].clone(), profiles);
let ccw_action = parse_key(encoder[1].clone(), profiles);
encoders.push(quote! { ::rmk::encoder!(#cw_action, #ccw_action) });
}
encoders.resize(
num_encoder,
quote! { ::rmk::encoder!(::rmk::k!(No), ::rmk::k!(No)) },
);
if encoders.is_empty() {
quote! { [::rmk::encoder!(::rmk::k!(No), ::rmk::k!(No)); NUM_ENCODER] }
} else {
quote! { [#(#encoders), *] }
}
}