#![cfg(test)]
use super::*;
use flexi_logger::Logger;
use log::*;
enum LogError {
CouldNotStartLogger,
}
fn setup_logging_lite() -> Result<(), LogError> {
match Logger::try_with_env_or_str("")
.unwrap()
.format(flexi_logger::colored_default_format)
.format_for_files(flexi_logger::colored_detailed_format)
.duplicate_to_stderr(flexi_logger::Duplicate::All)
.start()
{
Err(_) => Err(LogError::CouldNotStartLogger),
Ok(_) => Ok(()),
}
}
macro_rules! trigger_guide_alt {
(
$([
$([
$count:expr$(,$tc:expr)*$(,)?
]$(,)?)*
]$(,)?)*
) => {
unsafe { &[
$(
$(
$count,
$(
$tc.bytes()[0],
$tc.bytes()[1],
$tc.bytes()[2],
$tc.bytes()[3],
$tc.bytes()[4],
$tc.bytes()[5],
)*
)*
0,)*
] }
}
}
#[test]
fn trigger_condition_conversion() {
setup_logging_lite().ok();
let cond_a = TriggerCondition::Switch {
state: trigger::Phro::Press,
index: 1200,
loop_condition_index: 4,
};
unsafe {
let cond_b = TriggerCondition::from_bytes(cond_a.bytes());
assert_eq!(
cond_a,
cond_b,
"Check bytes and from_bytes conversions {:?} -> {:?} -> {:?}",
cond_a,
cond_a.bytes(),
cond_b
);
trace!("TriggerCondition::Switch -> {:?}", cond_a.bytes());
trace!(
"TriggerCondition -> {:?}",
TriggerCondition::from_bytes(cond_a.bytes())
);
}
}
#[test]
fn trigger_guide_macro() {
setup_logging_lite().ok();
const COND_A: &TriggerCondition = &TriggerCondition::Switch {
state: trigger::Phro::Press,
index: 1200,
loop_condition_index: 4,
};
const COND_B: &TriggerCondition = &TriggerCondition::Switch {
state: trigger::Phro::Press,
index: 2400,
loop_condition_index: 0,
};
const TRIGGER_GUIDES: &[u8] = trigger_guide_alt!(
[[2, COND_A, COND_B], [1, COND_A]],
[[1, COND_A]],
);
#[rustfmt::skip]
const TRIGGER_GUIDE_COMPARE: &[u8] = &[
2, 1, 1, 176, 4, 4, 0, 1, 1, 96, 9, 0, 0,
1, 1, 1, 176, 4, 4, 0,
0,
1, 1, 1, 176, 4, 4, 0,
0,
];
assert_eq!(
TRIGGER_GUIDES, TRIGGER_GUIDE_COMPARE,
"trigger_guide macro check failed: {:?} vs {:?}",
TRIGGER_GUIDES, TRIGGER_GUIDE_COMPARE
);
const TRIGGER_GUIDES2: &[u8] = kll_macros::trigger_guide!([
[
TriggerCondition::Switch {
state: trigger::Phro::Press,
index: 15,
loop_condition_index: 0
},
TriggerCondition::Switch {
state: trigger::Phro::Press,
index: 16,
loop_condition_index: 1
}
],
[TriggerCondition::Switch {
state: trigger::Phro::Release,
index: 15,
loop_condition_index: 0
}]
]);
#[rustfmt::skip]
const TRIGGER_GUIDE_COMPARE2: &[u8] = &[
2, 1, 1, 15, 0, 0, 0, 1, 1, 16, 0, 1, 0,
1, 1, 3, 15, 0, 0, 0,
0
];
assert_eq!(
TRIGGER_GUIDES2, TRIGGER_GUIDE_COMPARE2,
"trigger_guide macro check failed: {:?} vs {:?}",
TRIGGER_GUIDES2, TRIGGER_GUIDE_COMPARE2
);
}
#[test]
fn result_guide_macro() {
setup_logging_lite().ok();
const RESULT_GUIDES: &[u8] = kll_macros::result_guide!(
[[
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::A,
},
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::LeftShift,
},
],],
[[Capability::HidKeyboard {
state: CapabilityState::Last,
loop_condition_index: 0,
id: kll_hid::Keyboard::B,
},]],
);
#[rustfmt::skip]
const RESULT_GUIDE_COMPARE: &[u8] = &[
2, 6, 1, 0, 0, 4, 0, 0, 0, 6, 1, 0, 0, 225, 0, 0, 0,
1, 6, 2, 0, 0, 5, 0, 0, 0,
0,
];
assert_eq!(
RESULT_GUIDES, RESULT_GUIDE_COMPARE,
"result_guide macro check failed: {:?} vs {:?}",
RESULT_GUIDES, RESULT_GUIDE_COMPARE
);
}
#[test]
fn basic_init_test() {
setup_logging_lite().ok();
#[rustfmt::skip]
const LAYER_LOOKUP: &[u8] = kll_macros::layer_lookup!(
0, 1, 5, [],
0, 1, 6, [0, 2],
0, 1, 7, [0],
1, 0, 2, [],
1, 7, 3, [4],
2, 3, 8, [6],
2, 1, 6, [8],
);
const TRIGGER_RESULT_MAPPING: &[u16] = &[
0, 0, 13, 35, 20, 44, 27, 0, 13, 44, ];
const TRIGGER_GUIDES: &[u8] = kll_macros::trigger_guide!(
[[
TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 6,
loop_condition_index: 0,
},
TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 7,
loop_condition_index: 0,
},
]],
[[TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 6,
loop_condition_index: 0,
},]],
[[TriggerCondition::Layer {
state: trigger::LayerState::ShiftActivate,
layer: 3,
loop_condition_index: 0,
},]],
[[TriggerCondition::AnalogDistance {
reserved: 0,
index: 8,
val: 1500,
},]],
);
trace!("TRIGGER_GUIDES: {:?}", TRIGGER_GUIDES);
const RESULT_GUIDES: &[u8] = kll_macros::result_guide!(
[
[
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::A,
},
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::LeftShift,
},
],
[Capability::HidKeyboard {
state: CapabilityState::Last,
loop_condition_index: 0,
id: kll_hid::Keyboard::LeftShift,
},],
[Capability::HidKeyboard {
state: CapabilityState::Last,
loop_condition_index: 0,
id: kll_hid::Keyboard::A,
},],
],
[[Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::B,
},]],
[[Capability::HidKeyboard {
state: CapabilityState::Last,
loop_condition_index: 0,
id: kll_hid::Keyboard::B,
},]],
);
trace!("RESULT_GUIDES: {:?}", RESULT_GUIDES);
const LOOP_CONDITION_LOOKUP: &[u32] = &[0];
let lookup = LayerLookup::<256>::new(
LAYER_LOOKUP,
TRIGGER_GUIDES,
RESULT_GUIDES,
TRIGGER_RESULT_MAPPING,
LOOP_CONDITION_LOOKUP,
);
trace!("layer_lookup: {:?}", LAYER_LOOKUP);
for ((layer, ttype, index), mlookup) in &lookup.layer_lookup {
trace!("({}, {}, {}), {}", layer, ttype, index, mlookup);
}
trace!("TriggerList Lookup");
for (key, triggerlist) in [
((0, 1, 6), [0, 0, 2, 0]),
((1, 7, 3), [4, 0, 0, 0]),
((2, 3, 8), [6, 0, 0, 0]),
] {
match lookup.trigger_list(key) {
Some(mlookup) => {
trace!("{:?} -> {:?}", key, mlookup);
assert!(
mlookup == &triggerlist[..mlookup.len()],
"{:?} -> {:?} != {:?}",
key,
mlookup,
triggerlist
);
}
None => {
panic!("Missing key: {:?}", key);
}
}
}
assert!(
lookup.trigger_list((100, 100, 100)).is_none(),
"Failed 'Invalid' (100, 100, 100) lookup"
);
for (key, triggers, results) in [(
(0, 1, 6),
[
Some([
TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 6,
loop_condition_index: 0,
},
TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 7,
loop_condition_index: 0,
},
]),
Some([
TriggerCondition::Switch {
state: trigger::Phro::Hold,
index: 6,
loop_condition_index: 0,
},
TriggerCondition::None,
]),
],
[
Some([
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::A,
},
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::LeftShift,
},
]),
Some([
Capability::HidKeyboard {
state: CapabilityState::Initial,
loop_condition_index: 0,
id: kll_hid::Keyboard::B,
},
Capability::NoOp {
state: CapabilityState::Any,
loop_condition_index: 0,
},
]),
],
)] {
for (index, mapping) in lookup.lookup_guides::<10>(key).iter().enumerate() {
let trigger = lookup.trigger_guide(*mapping, 0);
let result = lookup.result_guide(*mapping, 0);
trace!(
"Mapping {:?} Trigger: {:?} Result: {:?}",
mapping,
trigger,
result
);
assert_eq!(
trigger.unwrap(),
&triggers[index].unwrap()[0..trigger.unwrap().len()],
"TriggerGuide did not match"
);
assert_eq!(
result.unwrap(),
&results[index].unwrap()[0..result.unwrap().len()],
"ResultGuide did not match"
);
}
}
}