diff options
| -rw-r--r-- | src/lib.rs | 58 |
1 files changed, 58 insertions, 0 deletions
@@ -44,6 +44,12 @@ struct Map { type MapCollection = HashMap<Trigger, MapAction>; +#[derive(Debug, PartialEq)] +struct Mode { + trigger: Trigger, + maps: MapCollection, +} + pub struct DKMapGroup { maps: MapCollection, modes: HashMap<Trigger, MapCollection>, @@ -149,6 +155,27 @@ where }) } +fn mode<I>() -> impl Parser<Input = I, Output = Mode> +where + I: Stream<Item = char>, + I::Error: ParseError<I::Item, I::Range, I::Position>, +{ + ( + string("mode"), + whitespace_separator(), + trigger(), + whitespace_separator(), + token('{'), + map_collection(), + token('}'), // Verify that this is parsed on its own line, not inside a map + ).map(|(_, _, trigger, _, _, collection, _)| + Mode { + trigger: trigger, + maps: collection, + } + ) +} + fn comment<I>() -> impl Parser<Input = I> where I: Stream<Item = char>, @@ -283,4 +310,35 @@ cmd <down> /usr/bin/say 'hello' assert_eq!(result, Ok(expected)); } + + #[test] + fn mode_parses_a_mode() { + let text = "mode <down><up> { + cmd <up><play> echo hello + map <down> insert {} + }"; + let result = mode().parse(text).map(|t| t.0); + + let mut expected = Mode { + trigger: vec![HeadphoneButton::Down, HeadphoneButton::Up], + maps: HashMap::new(), + }; + + expected.maps.insert( + vec![HeadphoneButton::Up, HeadphoneButton::Play], + MapAction { + action: "echo hello".to_owned(), + kind: MapKind::Command, + }, + ); + expected.maps.insert( + vec![HeadphoneButton::Down], + MapAction { + action: "insert {}".to_owned(), + kind: MapKind::Map, + }, + ); + + assert_eq!(result, Ok(expected)); + } } |
