From 88b9809210182dbd7e4c70dab91165b749e81d5a Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 16 Aug 2018 10:51:21 +0200 Subject: 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. --- src/lib.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) (limited to 'src') 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() -> impl Parser +where + I: Stream, + I::Error: ParseError, +{ + skip_many1(space().or(tab())) +} + +fn map_collection() -> impl Parser +where + I: Stream, + I::Error: ParseError, +{ + many::, _>( + ( + 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 test +cmd /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); + } } -- cgit v1.2.3