Skip to content

Commit

Permalink
fix(chordsv2): error on duplicate input keys
Browse files Browse the repository at this point in the history
  • Loading branch information
jtroo committed Oct 6, 2024
1 parent aa3b2dd commit 4967bce
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 20 deletions.
49 changes: 29 additions & 20 deletions parser/src/cfg/chord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub(crate) fn parse_defchordv2(
let mut chords_container = ChordsForKeys::<'static, KanataCustom> {
mapping: FxHashMap::default(),
};

let mut all_participating_key_sets = FxHashSet::default();

let all_chords = chunks
.by_ref()
.flat_map(|chunk| match chunk[0] {
Expand All @@ -36,11 +39,15 @@ pub(crate) fn parse_defchordv2(
let chord_definitions = parse_chord_file(file_name).unwrap();
let processed = chord_definitions.iter().map(|chord_def| {
let chunk = chord_translation.translate_chord(chord_def);
parse_single_chord(&chunk, s)
parse_single_chord(&chunk, s, &mut all_participating_key_sets)
});
Ok::<_, ParseError>(processed.collect_vec())
}
_ => Ok(vec![parse_single_chord(chunk, s)]),
_ => Ok(vec![parse_single_chord(
chunk,
s,
&mut all_participating_key_sets,
)]),
})
.flat_map(|vec_result| vec_result.into_iter())
.collect::<Vec<Result<_>>>();
Expand All @@ -51,25 +58,17 @@ pub(crate) fn parse_defchordv2(
if let Some(e) = unsuccessful.first() {
return Err((*e).clone());
}
let successful = all_chords.into_iter().filter_map(Result::ok).collect_vec();

let mut all_participating_key_sets = FxHashSet::default();
let successful = all_chords.into_iter().filter_map(Result::ok).collect_vec();
for chord in successful {
if !all_participating_key_sets.insert(chord.participating_keys) {
ParseError::new_without_span(
"This chord has previously been defined.\n\
Only one set of chords must exist for one key combination.",
);
} else {
for pkey in chord.participating_keys.iter().copied() {
//log::trace!("chord for key:{pkey:?} > {chord:?}");
chords_container
.mapping
.entry(pkey)
.or_insert(ChordsForKey { chords: vec![] })
.chords
.push(s.a.sref(chord.clone()));
}
for pkey in chord.participating_keys.iter().copied() {
//log::trace!("chord for key:{pkey:?} > {chord:?}");
chords_container
.mapping
.entry(pkey)
.or_insert(ChordsForKey { chords: vec![] })
.chords
.push(s.a.sref(chord.clone()));
}
}
let rem = chunks.remainder();
Expand All @@ -83,8 +82,18 @@ pub(crate) fn parse_defchordv2(
Ok(chords_container)
}

fn parse_single_chord(chunk: &[SExpr], s: &ParserState) -> Result<ChordV2<'static, KanataCustom>> {
fn parse_single_chord(
chunk: &[SExpr],
s: &ParserState,
all_participating_key_sets: &mut FxHashSet<Vec<u16>>,
) -> Result<ChordV2<'static, KanataCustom>> {
let participants = parse_participating_keys(&chunk[0], s)?;
if !all_participating_key_sets.insert(participants.clone()) {
bail_expr!(
&chunk[0],
"Duplicate participating-keys, key sets may be used only once."
);
}
let action = parse_action(&chunk[1], s)?;
let timeout = parse_timeout(&chunk[2], s)?;
let release_behaviour = parse_release_behaviour(&chunk[3], s)?;
Expand Down
17 changes: 17 additions & 0 deletions src/tests/sim_tests/chord_sim_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,20 @@ fn sim_chord_simultaneous_macro() {
result
);
}

#[test]
#[should_panic]
fn sim_chord_error_on_duplicate_keyset() {
simulate(
"
(defcfg concurrent-tap-hold yes)
(defsrc)
(deflayer base)
(defchordsv2-experimental
(1 2) (one-shot 2000 lsft) 20 all-released ()
(2 1) (one-shot 2000 lctl) 20 all-released ()
)
",
"",
);
}

0 comments on commit 4967bce

Please sign in to comment.