Minimal Imperative Parsing Library | https://docs.rs/mipl

add CollectWhile subparser

ecsolticia.codeberg.page f1b3efdb 5fbbbe68

verified
+65 -3
+2
src/parser/subparser.rs
··· 17 17 } 18 18 19 19 mod collect_till; 20 + mod collect_while; 20 21 pub use { 21 22 collect_till::CollectTill, 23 + collect_while::CollectWhile, 22 24 };
+3 -3
src/parser/subparser/collect_till.rs
··· 1 1 use super::*; 2 2 3 3 /// Consume tokens into a new parser until the concrete 4 - /// parser returns `None`. 4 + /// parser returns something. Stops when it hits `Some(_)`. 5 5 /// 6 - /// Said concrete pattern here 7 - /// is the generic parameter `Op`. 6 + /// Said concrete pattern here is provided by 7 + /// the generic parameter `Op`. 8 8 pub struct CollectTill<Op: parsers::Operator>(Op); 9 9 impl<Op> ConcreteSubparser<Op> for CollectTill<Op> 10 10 where
+37
src/parser/subparser/collect_while.rs
··· 1 + use super::*; 2 + 3 + /// Consume tokens into a new parser while the concrete 4 + /// parser returns something. Stop consuming if it returns 5 + /// `None`. 6 + /// 7 + /// Said concrete pattern here is provided by 8 + /// the generic parameter `Op`. 9 + pub struct CollectWhile<Op: parsers::Operator>(Op); 10 + impl<Op> ConcreteSubparser<Op> for CollectWhile<Op> 11 + where 12 + Op: parsers::Operator 13 + { 14 + fn subparse 15 + (value: <Op>::Input, parser: &mut Parser) -> Parser 16 + where 17 + Op: Container 18 + { 19 + let op = Op::new(value); 20 + 21 + let mut tokens = Tokens::new_empty(); 22 + 23 + loop { 24 + if let Some(_s) = op.peek_for(parser) { 25 + if let Some(tok) = parser.next() { 26 + tokens.add_token(tok) 27 + } else { 28 + panic!("Unexpected code path traced"); 29 + } 30 + } else { 31 + break; 32 + } 33 + } 34 + 35 + Parser::new(tokens) 36 + } 37 + }
+23
tests/test_subparser.rs
··· 45 45 } 46 46 assert_eq!(Some(k), subparser.next()) 47 47 } 48 + } 49 + 50 + #[test] 51 + fn test_collect_while_exact_match() { 52 + let mut parser = setup_space_seps_parser( 53 + "a a a a e f g h" 54 + ); 55 + let mut known_subparser = setup_space_seps_parser( 56 + "a a a a" 57 + ); 58 + 59 + let mut subparser = CollectWhile::<ExactMatch>::subparse( 60 + "a".to_string(), 61 + &mut parser 62 + ); 63 + 64 + println!("{:#?} {:#?}", known_subparser, subparser); 65 + 66 + let mut i: usize = 0; 67 + while i < 4 { 68 + assert_eq!(known_subparser.next(), subparser.next()); 69 + i += 1; 70 + } 48 71 }