diff options
| author | Teddy Wing | 2018-08-16 10:51:21 +0200 |
|---|---|---|
| committer | Teddy Wing | 2018-08-16 10:51:21 +0200 |
| commit | 88b9809210182dbd7e4c70dab91165b749e81d5a (patch) | |
| tree | 1c1d31a73cc7e6db4ca5254a0230c0256033bbcd /src | |
| parent | 21f4c4d10a4d0c8fbf997e8b8de9dd39942f1ca8 (diff) | |
| download | dome-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.rs | 80 |
1 files changed, 78 insertions, 2 deletions
@@ -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); + } } |
