diff options
| author | Teddy Wing | 2018-08-19 02:27:37 +0200 |
|---|---|---|
| committer | Teddy Wing | 2018-08-19 02:27:37 +0200 |
| commit | a528adb596d6e7ff2fedcee075356b49f29cf8ea (patch) | |
| tree | e8a6062073688da3b6e8ec16fb6ee101076316fd /src | |
| parent | afe9548b1d8fddb5492f492336afb8cc9944919f (diff) | |
| download | dome-key-map-a528adb596d6e7ff2fedcee075356b49f29cf8ea.tar.bz2 | |
Parse modes
Add a new `Mode` type to parse into, similar to the `Map` type we made
recently. Parse a mode definition, which contains a `MapCollection`.
Modes cannot contain other modes, so we don't bother worrying about
recursive parsers.
Diffstat (limited to 'src')
| -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)); + } } |
