aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2018-08-16 10:51:21 +0200
committerTeddy Wing2018-08-16 10:51:21 +0200
commit88b9809210182dbd7e4c70dab91165b749e81d5a (patch)
tree1c1d31a73cc7e6db4ca5254a0230c0256033bbcd /src
parent21f4c4d10a4d0c8fbf997e8b8de9dd39942f1ca8 (diff)
downloaddome-key-map-88b9809210182dbd7e4c70dab91165b749e81d5a.tar.bz2
Try to parse a `MapCollection`
Can't get this to work. Right now I'm getting this error when running my test: Err(Errors { position: PointerOffset(4522385157), errors: [Unexpected(Token('m')), Expected(Borrowed("lf newline")), Expected(Borrowed("whitespace")), Expected(Borrowed("tab"))] }) It's supposed to parse a set of map lines, including whitespace and comments, into a `MapCollection`. Right now I'm thinking I should split this up more and make a more fine-grained parser for just a single map line, then build up to the collection from there.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs80
1 files changed, 78 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 5fec41d..d10edd1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,10 +5,16 @@ use std::collections::HashMap;
use combine::*;
use combine::parser::choice::or;
-use combine::parser::char::{newline, string, string_cmp};
+use combine::parser::char::{
+ newline,
+ space,
+ string,
+ string_cmp,
+ tab,
+};
use combine::parser::repeat::take_until;
-#[derive(Debug, PartialEq)]
+#[derive(Debug, Hash, Eq, PartialEq)]
pub enum HeadphoneButton {
Play,
Up,
@@ -23,6 +29,7 @@ pub enum MapKind {
Command,
}
+#[derive(Debug)]
pub struct Map {
pub action: Action,
pub kind: MapKind,
@@ -81,6 +88,47 @@ where
take_until(newline())
}
+fn whitespace_separator<I>() -> impl Parser<Input = I>
+where
+ I: Stream<Item = char>,
+ I::Error: ParseError<I::Item, I::Range, I::Position>,
+{
+ skip_many1(space().or(tab()))
+}
+
+fn map_collection<I>() -> impl Parser<Input = I, Output = MapCollection>
+where
+ I: Stream<Item = char>,
+ I::Error: ParseError<I::Item, I::Range, I::Position>,
+{
+ many::<Vec<_>, _>(
+ (
+ skip_many(newline()),
+ whitespace_separator(),
+ map_kind(),
+ whitespace_separator(),
+ trigger(),
+ whitespace_separator(),
+ action(),
+ skip_many(newline()),
+ )
+ ).map(|collection| {
+ let mut maps = HashMap::new();
+
+ for (_, _, kind, _, trigger, _, action, _) in collection {
+ maps.insert(
+ trigger,
+ Map {
+ action: action,
+ kind: kind,
+ }
+ );
+ }
+
+ maps
+ })
+}
+
#[cfg(test)]
mod tests {
@@ -139,4 +187,32 @@ mod tests {
assert_eq!(result, Ok(expected));
}
+
+ #[test]
+ fn map_collection_parses_maps() {
+ let text = "
+map <up><down> test
+cmd <down> /usr/bin/say 'hello'
+";
+ let result = map_collection().easy_parse(text).map(|t| t.0);
+
+ let mut expected = HashMap::new();
+ expected.insert(
+ vec![HeadphoneButton::Up, HeadphoneButton::Down],
+ Map {
+ action: "test".to_owned(),
+ kind: MapKind::Map,
+ },
+ );
+ expected.insert(
+ vec![HeadphoneButton::Down],
+ Map {
+ action: "/usr/bin/say 'hello'".to_owned(),
+ kind: MapKind::Command,
+ },
+ );
+
+ // assert_eq!(result, Ok(expected));
+ println!("{:?}", result);
+ }
}