use std::fmt::Write as _;
use crate::config::{
Config,
constants::{
CONVERT_LAST_SEQUENCE, CONVERT_LAST_WORD, CONVERT_SELECTION, PAUSE,
SMART_CONVERT_LAST_SEQUENCE, SMART_CONVERT_LAST_WORD, SMART_CONVERT_SELECTION,
SWITCH_LAYOUT,
},
};
pub fn find_duplicate_hotkey_sequences(config: &Config) -> Option<String> {
let mut sequences = vec![
(CONVERT_LAST_WORD, &config.hotkey_convert_last_word_sequence),
(
CONVERT_LAST_SEQUENCE,
&config.hotkey_convert_last_sequence_sequence,
),
(PAUSE, &config.hotkey_pause_sequence),
(CONVERT_SELECTION, &config.hotkey_convert_selection_sequence),
(SWITCH_LAYOUT, &config.hotkey_switch_layout_sequence),
];
if config.smarter_hotkeys_enabled {
sequences.extend([
(
SMART_CONVERT_LAST_WORD,
&config.smart_hotkey_convert_last_word_sequence,
),
(
SMART_CONVERT_LAST_SEQUENCE,
&config.smart_hotkey_convert_last_sequence_sequence,
),
(
SMART_CONVERT_SELECTION,
&config.smart_hotkey_convert_selection_sequence,
),
]);
}
let is_allowed_duplicate = |a: &str, b: &str| {
(a == CONVERT_LAST_WORD && b == CONVERT_SELECTION)
|| (a == CONVERT_SELECTION && b == CONVERT_LAST_WORD)
|| (a == SMART_CONVERT_LAST_WORD && b == SMART_CONVERT_SELECTION)
|| (a == SMART_CONVERT_SELECTION && b == SMART_CONVERT_LAST_WORD)
};
let duplicates: Vec<_> = sequences
.iter()
.enumerate()
.filter_map(|(i, (name1, seq1_opt))| {
seq1_opt.as_ref().map(|seq1| {
sequences.iter().enumerate().skip(i + 1).filter_map(
move |(_j, (name2, seq2_opt))| {
seq2_opt
.as_ref()
.filter(|seq2| seq1 == *seq2 && !is_allowed_duplicate(name1, name2))
.map(|_| (*name1, *name2))
},
)
})
})
.flatten()
.collect();
if duplicates.is_empty() {
None
} else {
let mut error = String::from("Duplicate hotkey sequences found:\n\n");
for (name1, name2) in &duplicates {
let _ = writeln!(error, "• '{name1}' and '{name2}'");
}
error.push_str("\nEach action must have a unique hotkey sequence.");
Some(error)
}
}
impl Config {
pub fn validate_hotkey_sequences(&self) -> Result<(), String> {
if let Some(error) = find_duplicate_hotkey_sequences(self) {
Err(error)
} else {
Ok(())
}
}
}