1use evdev::Key;
14use std::collections::HashMap;
15use std::fmt;
16use std::sync::Arc;
17use tokio::sync::RwLock;
18use tracing::{debug, info};
19
20use crate::key_parser::{KeyParser, ParseError};
21use crate::layer_manager::LayerManager;
22
23pub type RemapTable = HashMap<Key, Key>;
39
40#[derive(Debug)]
42pub enum RemapError {
43 InvalidKey {
45 key: String,
46 source: String,
47 parse_error: String,
48 },
49
50 Config(String),
52
53 ParseError(ParseError),
55}
56
57impl fmt::Display for RemapError {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 match self {
60 RemapError::InvalidKey { key, source, parse_error } => {
61 write!(f, "Invalid key name '{}' in {}: {}", key, source, parse_error)
62 }
63 RemapError::Config(msg) => write!(f, "Configuration error: {}", msg),
64 RemapError::ParseError(e) => write!(f, "Parse error: {}", e),
65 }
66 }
67}
68
69impl std::error::Error for RemapError {}
70
71impl From<ParseError> for RemapError {
72 fn from(err: ParseError) -> Self {
73 RemapError::ParseError(err)
74 }
75}
76
77#[derive(Debug, Clone)]
89pub struct RemapProfile {
90 pub name: String,
92
93 pub remaps: Arc<RwLock<HashMap<Key, Key>>>,
96
97 key_parser: Arc<KeyParser>,
99}
100
101impl RemapProfile {
102 pub fn new(
125 name: String,
126 config: &HashMap<String, String>,
127 ) -> Result<Self, RemapError> {
128 let key_parser = Arc::new(KeyParser::new());
129 Self::with_key_parser(name, config, key_parser)
130 }
131
132 pub fn with_key_parser(
143 name: String,
144 config: &HashMap<String, String>,
145 key_parser: Arc<KeyParser>,
146 ) -> Result<Self, RemapError> {
147 let mut remaps = HashMap::new();
149
150 for (input_name, output_name) in config.iter() {
151 let input_key = key_parser.parse(input_name).map_err(|e| {
152 RemapError::InvalidKey {
153 key: input_name.clone(),
154 source: "input".to_string(),
155 parse_error: e.to_string(),
156 }
157 })?;
158
159 let output_key = key_parser.parse(output_name).map_err(|e| {
160 RemapError::InvalidKey {
161 key: output_name.clone(),
162 source: "output".to_string(),
163 parse_error: e.to_string(),
164 }
165 })?;
166
167 remaps.insert(input_key, output_key);
168 }
169
170 Ok(Self {
171 name,
172 remaps: Arc::new(RwLock::new(remaps)),
173 key_parser,
174 })
175 }
176
177 pub fn name(&self) -> &str {
179 &self.name
180 }
181
182 pub async fn remap_count(&self) -> usize {
184 self.remaps.read().await.len()
185 }
186
187 pub async fn has_remap(&self, key_code: Key) -> bool {
189 self.remaps.read().await.contains_key(&key_code)
190 }
191
192 pub async fn get_remaps(&self) -> HashMap<Key, Key> {
194 self.remaps.read().await.clone()
195 }
196
197 pub fn remaps_arc(&self) -> &Arc<RwLock<HashMap<Key, Key>>> {
211 &self.remaps
212 }
213
214 pub fn key_parser(&self) -> &Arc<KeyParser> {
216 &self.key_parser
217 }
218}
219
220pub struct RemapEngine {
248 remaps: Arc<RwLock<HashMap<Key, Key>>>,
252
253 layer_remaps: Vec<Arc<RwLock<HashMap<Key, Key>>>>,
257
258 layer_manager: Arc<RwLock<LayerManager>>,
260
261 key_parser: Arc<KeyParser>,
263}
264
265impl RemapEngine {
266 pub fn new() -> Self {
270 let layer_remaps = vec![
272 Arc::new(RwLock::new(HashMap::new())), Arc::new(RwLock::new(HashMap::new())), Arc::new(RwLock::new(HashMap::new())), ];
276
277 Self {
278 remaps: Arc::new(RwLock::new(HashMap::new())),
279 layer_remaps,
280 layer_manager: Arc::new(RwLock::new(LayerManager::new(None))),
281 key_parser: Arc::new(KeyParser::new()),
282 }
283 }
284
285 pub fn with_key_parser(key_parser: Arc<KeyParser>) -> Self {
289 let layer_remaps = vec![
290 Arc::new(RwLock::new(HashMap::new())), Arc::new(RwLock::new(HashMap::new())), Arc::new(RwLock::new(HashMap::new())), ];
294
295 Self {
296 remaps: Arc::new(RwLock::new(HashMap::new())),
297 layer_remaps,
298 layer_manager: Arc::new(RwLock::new(LayerManager::new(None))),
299 key_parser,
300 }
301 }
302
303 pub fn set_layer_manager(&mut self, layer_manager: Arc<RwLock<LayerManager>>) {
313 self.layer_manager = layer_manager;
314 }
315
316 pub async fn load_layer_remap(
343 &self,
344 layer_id: usize,
345 config: &HashMap<String, String>,
346 ) -> Result<(), RemapError> {
347 if layer_id >= self.layer_remaps.len() {
349 return Err(RemapError::Config(format!(
350 "Layer ID {} exceeds available layers ({} layers configured)",
351 layer_id,
352 self.layer_remaps.len()
353 )));
354 }
355
356 info!("Loading key remap configuration for layer {}", layer_id);
357
358 let mut parsed_remaps = HashMap::new();
360
361 for (input_name, output_name) in config.iter() {
362 let input_key = self.key_parser.parse(input_name).map_err(|e| {
364 RemapError::InvalidKey {
365 key: input_name.clone(),
366 source: "input".to_string(),
367 parse_error: e.to_string(),
368 }
369 })?;
370
371 let output_key = self.key_parser.parse(output_name).map_err(|e| {
373 RemapError::InvalidKey {
374 key: output_name.clone(),
375 source: "output".to_string(),
376 parse_error: e.to_string(),
377 }
378 })?;
379
380 parsed_remaps.insert(input_key, output_key);
382
383 debug!("Layer {} remap: {} -> {}", layer_id, input_name, output_name);
384 }
385
386 let mut layer_remap = self.layer_remaps[layer_id].write().await;
388 *layer_remap = parsed_remaps;
389
390 if layer_id == 0 {
392 let mut remaps = self.remaps.write().await;
393 *remaps = layer_remap.clone();
394 }
395
396 info!(
397 "Loaded {} key remappings for layer {} successfully",
398 layer_remap.len(),
399 layer_id
400 );
401
402 Ok(())
403 }
404
405 pub fn layer_count(&self) -> usize {
411 self.layer_remaps.len()
412 }
413
414 pub async fn load_config(
441 &self,
442 config: &HashMap<String, String>,
443 ) -> Result<(), RemapError> {
444 info!("Loading key remap configuration");
445
446 let mut parsed_remaps = HashMap::new();
448
449 for (input_name, output_name) in config.iter() {
450 let input_key = self.key_parser.parse(input_name).map_err(|e| {
452 RemapError::InvalidKey {
453 key: input_name.clone(),
454 source: "input".to_string(),
455 parse_error: e.to_string(),
456 }
457 })?;
458
459 let output_key = self.key_parser.parse(output_name).map_err(|e| {
461 RemapError::InvalidKey {
462 key: output_name.clone(),
463 source: "output".to_string(),
464 parse_error: e.to_string(),
465 }
466 })?;
467
468 parsed_remaps.insert(input_key, output_key);
470
471 debug!("Remap: {} -> {}", input_name, output_name);
472 }
473
474 let mut remaps = self.remaps.write().await;
476 *remaps = parsed_remaps;
477
478 info!(
479 "Loaded {} key remappings successfully",
480 remaps.len()
481 );
482
483 Ok(())
484 }
485
486 pub async fn remap(&self, key_code: Key) -> Option<Key> {
513 let remaps = self.remaps.read().await;
514 let output = remaps.get(&key_code).copied();
515
516 if let Some(out) = output {
517 debug!("Remapped {:?} -> {:?}", key_code, out);
518 }
519
520 output
521 }
522
523 pub async fn process_event(&self, key_code: Key, value: i32) -> Option<(Key, i32)> {
552 let remaps = self.remaps.read().await;
553
554 if let Some(&output_key) = remaps.get(&key_code) {
555 Some((output_key, value))
558 } else {
559 None
560 }
561 }
562
563 pub async fn remap_count(&self) -> usize {
569 let remaps = self.remaps.read().await;
570 remaps.len()
571 }
572
573 pub async fn has_remap(&self, key_code: Key) -> bool {
583 let remaps = self.remaps.read().await;
584 remaps.contains_key(&key_code)
585 }
586
587 pub async fn clear(&self) {
591 let mut remaps = self.remaps.write().await;
592 let count = remaps.len();
593 remaps.clear();
594 info!("Cleared {} key remappings", count);
595 }
596
597 pub fn key_parser(&self) -> &Arc<KeyParser> {
601 &self.key_parser
602 }
603
604 pub async fn get_remaps(&self) -> HashMap<Key, Key> {
608 let remaps = self.remaps.read().await;
609 remaps.clone()
610 }
611
612 pub async fn remap_layer_aware(&self, device_id: &str, key_code: Key) -> Option<Key> {
643 let effective_layer = self.layer_manager.read().await.get_effective_layer(device_id).await;
645
646 for layer_id in (0..=effective_layer).rev() {
648 if let Some(remaps) = self.layer_remaps.get(layer_id) {
649 let remap_table = remaps.read().await;
650 if let Some(&output_key) = remap_table.get(&key_code) {
651 debug!(
652 "Layer-aware remap: device {} key {:?} -> {:?} (from layer {})",
653 device_id, key_code, output_key, layer_id
654 );
655 return Some(output_key);
656 }
657 }
658 }
659
660 debug!(
662 "Layer-aware remap: device {} key {:?} not found in any layer (effective: {})",
663 device_id, key_code, effective_layer
664 );
665 None
666 }
667
668 pub async fn process_event_layer_aware(
700 &self,
701 device_id: &str,
702 key_code: Key,
703 value: i32,
704 ) -> Option<(Key, i32)> {
705 let effective_layer = self.layer_manager.read().await.get_effective_layer(device_id).await;
707
708 for layer_id in (0..=effective_layer).rev() {
710 if let Some(remaps) = self.layer_remaps.get(layer_id) {
711 let remap_table = remaps.read().await;
712 if let Some(&output_key) = remap_table.get(&key_code) {
713 debug!(
714 "Layer-aware event: device {} key {:?} -> {:?} (value: {}, from layer {})",
715 device_id, key_code, output_key, value, layer_id
716 );
717 return Some((output_key, value));
718 }
719 }
720 }
721
722 None
724 }
725
726 pub fn layer_manager(&self) -> &Arc<RwLock<LayerManager>> {
730 &self.layer_manager
731 }
732
733 pub async fn get_layer_remaps(&self, layer_id: usize) -> Option<HashMap<Key, Key>> {
747 if let Some(remaps) = self.layer_remaps.get(layer_id) {
748 let remap_table = remaps.read().await;
749 Some(remap_table.clone())
750 } else {
751 None
752 }
753 }
754}
755
756impl Default for RemapEngine {
757 fn default() -> Self {
758 Self::new()
759 }
760}
761
762#[cfg(test)]
763mod tests {
764 use super::*;
765
766 #[tokio::test]
767 async fn test_remap_engine_creation() {
768 let engine = RemapEngine::new();
769 assert_eq!(engine.remap_count().await, 0);
770 }
771
772 #[tokio::test]
773 async fn test_load_config_basic() {
774 let engine = RemapEngine::new();
775
776 let mut config = HashMap::new();
777 config.insert("KEY_A".to_string(), "KEY_B".to_string());
778
779 let result = engine.load_config(&config).await;
780 assert!(result.is_ok());
781 assert_eq!(engine.remap_count().await, 1);
782 }
783
784 #[tokio::test]
785 async fn test_load_config_with_friendly_names() {
786 let engine = RemapEngine::new();
787
788 let mut config = HashMap::new();
789 config.insert("a".to_string(), "b".to_string());
790 config.insert("capslock".to_string(), "leftctrl".to_string());
791
792 let result = engine.load_config(&config).await;
793 assert!(result.is_ok());
794 assert_eq!(engine.remap_count().await, 2);
795 }
796
797 #[tokio::test]
798 async fn test_remap_returns_correct_key() {
799 let engine = RemapEngine::new();
800
801 let mut config = HashMap::new();
802 config.insert("KEY_A".to_string(), "KEY_B".to_string());
803
804 engine.load_config(&config).await.unwrap();
805
806 let result = engine.remap(Key::KEY_A).await;
808 assert_eq!(result, Some(Key::KEY_B));
809
810 let result = engine.remap(Key::KEY_C).await;
812 assert_eq!(result, None);
813 }
814
815 #[tokio::test]
816 async fn test_invalid_input_key_fails_validation() {
817 let engine = RemapEngine::new();
818
819 let mut config = HashMap::new();
820 config.insert("nonexistent_key".to_string(), "KEY_B".to_string());
821
822 let result = engine.load_config(&config).await;
823 assert!(result.is_err());
824
825 match result {
826 Err(RemapError::InvalidKey { key, source, .. }) => {
827 assert_eq!(key, "nonexistent_key");
828 assert_eq!(source, "input");
829 }
830 _ => panic!("Expected InvalidKey error"),
831 }
832 }
833
834 #[tokio::test]
835 async fn test_invalid_output_key_fails_validation() {
836 let engine = RemapEngine::new();
837
838 let mut config = HashMap::new();
839 config.insert("KEY_A".to_string(), "nonexistent_key".to_string());
840
841 let result = engine.load_config(&config).await;
842 assert!(result.is_err());
843
844 match result {
845 Err(RemapError::InvalidKey { key, source, .. }) => {
846 assert_eq!(key, "nonexistent_key");
847 assert_eq!(source, "output");
848 }
849 _ => panic!("Expected InvalidKey error"),
850 }
851 }
852
853 #[tokio::test]
854 async fn test_eager_validation_no_partial_load() {
855 let engine = RemapEngine::new();
856
857 let mut config = HashMap::new();
858 config.insert("KEY_A".to_string(), "KEY_B".to_string());
860 config.insert("KEY_C".to_string(), "invalid_key".to_string());
862
863 let result = engine.load_config(&config).await;
864
865 assert!(result.is_err());
867
868 assert_eq!(engine.remap_count().await, 0);
870 }
871
872 #[tokio::test]
873 async fn test_case_insensitive_config() {
874 let engine = RemapEngine::new();
875
876 let mut config = HashMap::new();
877 config.insert("key_a".to_string(), "KEY_B".to_string());
878 config.insert("CAPSLOCK".to_string(), "leftctrl".to_string());
879
880 let result = engine.load_config(&config).await;
881 assert!(result.is_ok());
882 assert_eq!(engine.remap_count().await, 2);
883
884 assert_eq!(engine.remap(Key::KEY_A).await, Some(Key::KEY_B));
886 assert_eq!(engine.remap(Key::KEY_CAPSLOCK).await, Some(Key::KEY_LEFTCTRL));
887 }
888
889 #[tokio::test]
890 async fn test_has_remap() {
891 let engine = RemapEngine::new();
892
893 assert!(!engine.has_remap(Key::KEY_A).await);
894
895 let mut config = HashMap::new();
896 config.insert("KEY_A".to_string(), "KEY_B".to_string());
897 engine.load_config(&config).await.unwrap();
898
899 assert!(engine.has_remap(Key::KEY_A).await);
900 assert!(!engine.has_remap(Key::KEY_C).await);
901 }
902
903 #[tokio::test]
904 async fn test_clear_remaps() {
905 let engine = RemapEngine::new();
906
907 let mut config = HashMap::new();
908 config.insert("KEY_A".to_string(), "KEY_B".to_string());
909 config.insert("KEY_C".to_string(), "KEY_D".to_string());
910 engine.load_config(&config).await.unwrap();
911
912 assert_eq!(engine.remap_count().await, 2);
913
914 engine.clear().await;
915 assert_eq!(engine.remap_count().await, 0);
916 }
917
918 #[tokio::test]
919 async fn test_complex_remap_scenario() {
920 let engine = RemapEngine::new();
921
922 let mut config = HashMap::new();
924 config.insert("capslock".to_string(), "leftctrl".to_string());
925 config.insert("esc".to_string(), "grave".to_string());
926
927 engine.load_config(&config).await.unwrap();
928
929 assert_eq!(engine.remap(Key::KEY_CAPSLOCK).await, Some(Key::KEY_LEFTCTRL));
931 assert_eq!(engine.remap(Key::KEY_ESC).await, Some(Key::KEY_GRAVE));
933 }
934
935 #[tokio::test]
936 async fn test_shared_key_parser() {
937 let parser = Arc::new(KeyParser::new());
938 let _engine = RemapEngine::with_key_parser(parser.clone());
939
940 assert_eq!(parser.parse("a"), Ok(Key::KEY_A));
942 }
943
944 #[tokio::test]
945 async fn test_get_remaps() {
946 let engine = RemapEngine::new();
947
948 let mut config = HashMap::new();
949 config.insert("KEY_A".to_string(), "KEY_B".to_string());
950
951 engine.load_config(&config).await.unwrap();
952
953 let remaps = engine.get_remaps().await;
954 assert_eq!(remaps.len(), 1);
955 assert_eq!(remaps.get(&Key::KEY_A), Some(&Key::KEY_B));
956 }
957
958 #[tokio::test]
959 async fn test_remap_to_none_for_unmapped_keys() {
960 let engine = RemapEngine::new();
961
962 let mut config = HashMap::new();
963 config.insert("KEY_A".to_string(), "KEY_B".to_string());
964
965 engine.load_config(&config).await.unwrap();
966
967 assert!(engine.remap(Key::KEY_A).await.is_some());
969
970 assert!(engine.remap(Key::KEY_Z).await.is_none());
972 assert!(engine.remap(Key::KEY_0).await.is_none());
973 }
974
975 #[tokio::test]
978 async fn test_remap_profile_creation() {
979 let mut config = HashMap::new();
980 config.insert("capslock".to_string(), "leftctrl".to_string());
981 config.insert("a".to_string(), "b".to_string());
982
983 let profile = RemapProfile::new("test-profile".to_string(), &config);
984 assert!(profile.is_ok());
985
986 let profile = profile.unwrap();
987 assert_eq!(profile.name(), "test-profile");
988 assert_eq!(profile.remap_count().await, 2);
989 }
990
991 #[tokio::test]
992 async fn test_remap_profile_invalid_key_fails() {
993 let mut config = HashMap::new();
994 config.insert("invalid_key".to_string(), "KEY_A".to_string());
995
996 let result = RemapProfile::new("bad-profile".to_string(), &config);
997 assert!(result.is_err());
998 }
999
1000 #[tokio::test]
1001 async fn test_remap_profile_arc_cloning() {
1002 let mut config = HashMap::new();
1003 config.insert("KEY_A".to_string(), "KEY_B".to_string());
1004
1005 let profile1 = RemapProfile::new("profile1".to_string(), &config).unwrap();
1006 let profile2 = profile1.clone();
1007
1008 assert_eq!(profile1.name(), profile2.name());
1010 assert_eq!(profile1.remap_count().await, profile2.remap_count().await);
1011 }
1012
1013 #[tokio::test]
1016 async fn test_layer_remap_creation() {
1017 let engine = RemapEngine::new();
1018
1019 assert_eq!(engine.layer_count(), 3);
1021
1022 let layer_0 = engine.get_layer_remaps(0).await;
1024 let layer_1 = engine.get_layer_remaps(1).await;
1025 let layer_2 = engine.get_layer_remaps(2).await;
1026
1027 assert!(layer_0.is_some());
1028 assert!(layer_1.is_some());
1029 assert!(layer_2.is_some());
1030
1031 assert!(layer_0.unwrap().is_empty());
1032 assert!(layer_1.unwrap().is_empty());
1033 assert!(layer_2.unwrap().is_empty());
1034
1035 assert!(engine.get_layer_remaps(3).await.is_none());
1037 }
1038
1039 #[tokio::test]
1040 async fn test_load_layer_remap() {
1041 let engine = RemapEngine::new();
1042
1043 let mut config = HashMap::new();
1045 config.insert("KEY_A".to_string(), "KEY_X".to_string());
1046 config.insert("KEY_B".to_string(), "KEY_Y".to_string());
1047
1048 let result = engine.load_layer_remap(1, &config).await;
1049 assert!(result.is_ok());
1050
1051 let layer_1 = engine.get_layer_remaps(1).await.unwrap();
1053 assert_eq!(layer_1.len(), 2);
1054 assert_eq!(layer_1.get(&Key::KEY_A), Some(&Key::KEY_X));
1055 assert_eq!(layer_1.get(&Key::KEY_B), Some(&Key::KEY_Y));
1056
1057 let layer_0 = engine.get_layer_remaps(0).await.unwrap();
1059 assert!(layer_0.is_empty());
1060 }
1061
1062 #[tokio::test]
1063 async fn test_load_layer_remap_invalid_layer() {
1064 let engine = RemapEngine::new();
1065
1066 let mut config = HashMap::new();
1067 config.insert("KEY_A".to_string(), "KEY_B".to_string());
1068
1069 let result = engine.load_layer_remap(5, &config).await;
1071 assert!(result.is_err());
1072
1073 match result {
1074 Err(RemapError::Config(msg)) => {
1075 assert!(msg.contains("Layer ID 5"));
1076 assert!(msg.contains("exceeds available layers"));
1077 }
1078 _ => panic!("Expected Config error with layer ID message"),
1079 }
1080 }
1081
1082 #[tokio::test]
1083 async fn test_remap_layer_aware_base_layer() {
1084 let engine = RemapEngine::new();
1085
1086 let mut config = HashMap::new();
1088 config.insert("KEY_A".to_string(), "KEY_B".to_string());
1089
1090 engine.load_layer_remap(0, &config).await.unwrap();
1091
1092 let result = engine.remap_layer_aware("test_device", Key::KEY_A).await;
1094 assert_eq!(result, Some(Key::KEY_B));
1095
1096 let result = engine.remap_layer_aware("test_device", Key::KEY_C).await;
1098 assert_eq!(result, None);
1099 }
1100
1101 #[tokio::test]
1102 async fn test_remap_layer_aware_cascade() {
1103 let engine = RemapEngine::new();
1104
1105 let mut base_config = HashMap::new();
1108 base_config.insert("KEY_A".to_string(), "KEY_B".to_string());
1109 base_config.insert("KEY_C".to_string(), "KEY_D".to_string());
1110 engine.load_layer_remap(0, &base_config).await.unwrap();
1111
1112 let mut layer1_config = HashMap::new();
1114 layer1_config.insert("KEY_A".to_string(), "KEY_X".to_string());
1115 engine.load_layer_remap(1, &layer1_config).await.unwrap();
1116
1117 engine.layer_manager.write().await.activate_hold_layer("test_device", 1).await.unwrap();
1119
1120 let result = engine.remap_layer_aware("test_device", Key::KEY_A).await;
1122 assert_eq!(result, Some(Key::KEY_X));
1123
1124 let result = engine.remap_layer_aware("test_device", Key::KEY_C).await;
1126 assert_eq!(result, Some(Key::KEY_D));
1127 }
1128
1129 #[tokio::test]
1130 async fn test_remap_layer_aware_priority() {
1131 let engine = RemapEngine::new();
1132
1133 let mut base_config = HashMap::new();
1135 base_config.insert("KEY_A".to_string(), "KEY_B".to_string());
1136 engine.load_layer_remap(0, &base_config).await.unwrap();
1137
1138 let mut layer1_config = HashMap::new();
1140 layer1_config.insert("KEY_A".to_string(), "KEY_X".to_string());
1141 engine.load_layer_remap(1, &layer1_config).await.unwrap();
1142
1143 let mut layer2_config = HashMap::new();
1145 layer2_config.insert("KEY_A".to_string(), "KEY_Y".to_string());
1146 engine.load_layer_remap(2, &layer2_config).await.unwrap();
1147
1148 let lm = engine.layer_manager.write().await;
1150 lm.activate_hold_layer("test_device", 1).await.unwrap();
1151 lm.activate_hold_layer("test_device", 2).await.unwrap();
1152 drop(lm);
1153
1154 let result = engine.remap_layer_aware("test_device", Key::KEY_A).await;
1156 assert_eq!(result, Some(Key::KEY_Y));
1157
1158 engine.layer_manager.write().await.deactivate_hold_layer("test_device", 2).await.unwrap();
1160 let result = engine.remap_layer_aware("test_device", Key::KEY_A).await;
1161 assert_eq!(result, Some(Key::KEY_X));
1162
1163 engine.layer_manager.write().await.deactivate_hold_layer("test_device", 1).await.unwrap();
1165 let result = engine.remap_layer_aware("test_device", Key::KEY_A).await;
1166 assert_eq!(result, Some(Key::KEY_B));
1167 }
1168
1169 #[tokio::test]
1170 async fn test_remap_layer_aware_no_remap() {
1171 let engine = RemapEngine::new();
1172
1173 let mut config = HashMap::new();
1175 config.insert("KEY_A".to_string(), "KEY_B".to_string());
1176 engine.load_layer_remap(0, &config).await.unwrap();
1177
1178 engine.layer_manager.write().await.activate_layer("test_device", 1).await;
1180
1181 let result = engine.remap_layer_aware("test_device", Key::KEY_Z).await;
1183 assert_eq!(result, None);
1184 }
1185
1186 #[tokio::test]
1187 async fn test_process_event_layer_aware() {
1188 let engine = RemapEngine::new();
1189
1190 let mut config = HashMap::new();
1192 config.insert("KEY_A".to_string(), "KEY_X".to_string());
1193 engine.load_layer_remap(1, &config).await.unwrap();
1194
1195 engine.layer_manager.write().await.activate_hold_layer("test_device", 1).await.unwrap();
1197
1198 let result = engine.process_event_layer_aware("test_device", Key::KEY_A, 1).await;
1200 assert_eq!(result, Some((Key::KEY_X, 1)));
1201
1202 let result = engine.process_event_layer_aware("test_device", Key::KEY_A, 0).await;
1204 assert_eq!(result, Some((Key::KEY_X, 0)));
1205
1206 let result = engine.process_event_layer_aware("test_device", Key::KEY_A, 2).await;
1208 assert_eq!(result, Some((Key::KEY_X, 2)));
1209
1210 let result = engine.process_event_layer_aware("test_device", Key::KEY_Z, 1).await;
1212 assert_eq!(result, None);
1213 }
1214
1215 #[tokio::test]
1216 async fn test_layer_manager_accessor() {
1217 let engine = RemapEngine::new();
1218
1219 let layer_manager = engine.layer_manager();
1221
1222 layer_manager.write().await.activate_layer("test_device", 1).await;
1224
1225 let effective = layer_manager.read().await.get_effective_layer("test_device").await;
1227 assert_eq!(effective, 1);
1228 }
1229
1230 #[tokio::test]
1231 async fn test_multiple_devices_independent_layers() {
1232 let engine = RemapEngine::new();
1233
1234 let mut config1 = HashMap::new();
1236 config1.insert("KEY_A".to_string(), "KEY_X".to_string());
1237 engine.load_layer_remap(1, &config1).await.unwrap();
1238
1239 let mut config2 = HashMap::new();
1240 config2.insert("KEY_A".to_string(), "KEY_Y".to_string());
1241 engine.load_layer_remap(2, &config2).await.unwrap();
1242
1243 let lm = engine.layer_manager.write().await;
1245 lm.activate_hold_layer("device1", 1).await.unwrap();
1246 lm.activate_hold_layer("device2", 2).await.unwrap();
1247 drop(lm);
1248
1249 let result1 = engine.remap_layer_aware("device1", Key::KEY_A).await;
1251 assert_eq!(result1, Some(Key::KEY_X));
1252
1253 let result2 = engine.remap_layer_aware("device2", Key::KEY_A).await;
1255 assert_eq!(result2, Some(Key::KEY_Y));
1256
1257 let result3 = engine.remap_layer_aware("device3", Key::KEY_A).await;
1259 assert_eq!(result3, None);
1260 }
1261
1262 #[tokio::test]
1263 async fn test_load_layer_remap_eager_validation() {
1264 let engine = RemapEngine::new();
1265
1266 let mut config = HashMap::new();
1267 config.insert("KEY_A".to_string(), "KEY_B".to_string());
1269 config.insert("KEY_C".to_string(), "invalid_key".to_string());
1271
1272 let result = engine.load_layer_remap(1, &config).await;
1274 assert!(result.is_err());
1275
1276 let layer_1 = engine.get_layer_remaps(1).await.unwrap();
1278 assert!(layer_1.is_empty());
1279 }
1280}