aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2018-08-19 02:27:37 +0200
committerTeddy Wing2018-08-19 02:27:37 +0200
commita528adb596d6e7ff2fedcee075356b49f29cf8ea (patch)
treee8a6062073688da3b6e8ec16fb6ee101076316fd
parentafe9548b1d8fddb5492f492336afb8cc9944919f (diff)
downloaddome-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.
-rw-r--r--src/lib.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index df490e5..aebf43b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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));
+ }
}