termusiclib/config/v2/tui/keys/
conflict.rs1use ahash::HashMap;
2
3use super::KeyBinding;
4
5#[derive(Debug, Clone, PartialEq)]
7pub(super) struct KeyPath(Vec<&'static str>);
8
9impl KeyPath {
10 pub fn new() -> Self {
11 Self(Vec::new())
12 }
13
14 pub fn new_with_toplevel(value: &'static str) -> Self {
15 let mut ret = Self::new();
16 ret.push(value);
17
18 ret
19 }
20
21 pub fn push(&mut self, value: &'static str) {
23 self.0.push(value);
24 }
25
26 pub fn pop(&mut self) -> Option<&'static str> {
28 self.0.pop()
29 }
30
31 pub fn join_with_field(&self, field: &'static str) -> String {
33 let mut ret = self.0.join(".");
34
35 ret.push('.');
36 ret.push_str(field);
37
38 ret
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, thiserror::Error)]
44#[error("Key Conflict: '{key_path_first}' and '{key_path_second}', key: '{key}'")]
45pub struct KeyConflictError {
46 pub key_path_first: String,
47 pub key_path_second: String,
48 pub key: KeyBinding,
49}
50
51pub(super) type KeyHashMap = HashMap<&'static KeyBinding, &'static str>;
52pub(super) type KeyHashMapOwned = HashMap<KeyBinding, String>;
53
54pub(super) trait CheckConflict {
55 fn iter(&self) -> impl Iterator<Item = (&KeyBinding, &'static str)>;
61 fn check_conflict(
63 &self,
64 key_path: &mut KeyPath,
65 global_keys: &mut KeyHashMapOwned,
66 ) -> Result<(), Vec<KeyConflictError>>;
67}
68
69#[macro_export]
86macro_rules! once_chain {
87 (
88 $first:expr
89 $(
90 , $second:expr
91 )* $(,)?
92 ) => {
93 std::iter::once($first)
94 $(.chain(std::iter::once($second)))*
95 }
96}