aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2018-08-17 03:29:35 +0200
committerTeddy Wing2018-08-17 03:29:35 +0200
commitf026d7521f17736fe4f44c1ab052328d423f3a5c (patch)
tree08347e990736e3ac308f9c7c12ce6a9abc2187ac /src
parentae48205ed1549678835574f962c7d2c62704d147 (diff)
downloaddome-key-map-f026d7521f17736fe4f44c1ab052328d423f3a5c.tar.bz2
Parse a single-element `MapCollection`
Managed to get `MapCollection` parsing working, but only for a single mapping for now. Need to figure out what I'm doing wrong. Here's the result of my test: thread 'tests::map_collection_parses_maps' panicked at 'assertion failed: `(left == right)` left: `Ok({[Up, Down]: MapAction { action: "test", kind: Map }})`, right: `Ok({[Down]: MapAction { action: "/usr/bin/say \'hello\'", kind: Command }, [Up, Down]: MapAction { action: "test", kind: Map }})`', src/lib.rs:265:9 note: Run with `RUST_BACKTRACE=1` for a backtrace. test tests::map_collection_parses_maps ... FAILED At first the assertion in the test wasn't working, failing to compile with this error: error[E0369]: binary operation `==` cannot be applied to type `std::collections::HashMap<std::vec::Vec<HeadphoneButton>, MapAction>` --> src/lib.rs:266:9 | 266 | assert_eq!(result.unwrap(), expected); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `std::collections::HashMap<std::vec::Vec<HeadphoneButton>, MapAction>` = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) Finally realised that I needed to derive `PartialEq` on `MapAction` to make it work. Added a comment parser, based on the `examples/ini.rs` example from Combine: fn whitespace<I>() -> impl Parser<Input = I> where I: Stream<Item = char>, I::Error: ParseError<I::Item, I::Range, I::Position>, { let comment = (token(';'), skip_many(satisfy(|c| c != '\n'))).map(|_| ()); // Wrap the `spaces().or(comment)` in `skip_many` so that it skips alternating whitespace and // comments skip_many(skip_many1(space()).or(comment)) } Tried writing a test for `comment()`, but couldn't get it to work, presumably because `comment()` doesn't have any output: #[test] fn comment_parses_line_comments() { let text = "# This is a comment "; let result = comment().parse(text).map(|t| t.0); // print!("{:?}", result); assert_eq!(result, Ok(())); }
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs45
1 files changed, 26 insertions, 19 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 5dbf477..c912897 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,7 +29,7 @@ pub enum MapKind {
Command,
}
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
pub struct MapAction {
pub action: Action,
pub kind: MapKind,
@@ -129,26 +129,21 @@ 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 comment = comment().map(|_| ());
+ let blank = skip_many(newline()).or(comment);
+
+ (
+ blank,
+ many::<Vec<Map>, _>(map()),
+ ).map(|(_, collection)| {
let mut maps = HashMap::new();
- for (_, _, kind, _, trigger, _, action, _) in collection {
+ for map in collection {
maps.insert(
- trigger,
+ map.trigger,
MapAction {
- action: action,
- kind: kind,
+ action: map.action,
+ kind: map.kind,
}
);
}
@@ -157,6 +152,19 @@ where
})
}
+fn comment<I>() -> impl Parser<Input = I>
+where
+ I: Stream<Item = char>,
+ I::Error: ParseError<I::Item, I::Range, I::Position>,
+{
+ skip_many(
+ (
+ token('#'),
+ skip_many(satisfy(|c| c != '\n')),
+ )// .map(|_| ())
+ )
+}
+
#[cfg(test)]
mod tests {
@@ -254,7 +262,6 @@ cmd <down> /usr/bin/say 'hello'
},
);
- // assert_eq!(result, Ok(expected));
- println!("{:?}", result);
+ assert_eq!(result, Ok(expected));
}
}