From 157c1db358bf31dc9a409a1a9d9b5d4e57936f31 Mon Sep 17 00:00:00 2001 From: John Turner Date: Sun, 26 Oct 2025 01:10:37 -0400 Subject: impl Regex parser --- src/lib.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 930acfe..050ed52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1002,6 +1002,35 @@ where take_while1(r#if(|c: &I::Item| c.is_whitespace())) } +pub mod str { + + use super::*; + + struct Regex(regex::Regex); + + impl<'a> Parser<&'a str> for Regex { + type Output = &'a str; + + fn run>( + &self, + it: InputIter<&'a str>, + ) -> ParserResult<&'a str, Self::Output, OM, EM> { + match self.0.find(it.rest()) { + Some(m) => { + let output = OM::bind(|| it.rest().slice(m.range())); + let (rest, _) = take(m.end()).parse(it).unwrap(); + Ok((rest, output)) + } + None => return Err(EM::bind(|| it.clone())), + } + } + } + + pub fn regex<'a>(pattern: &'a str) -> impl Parser<&'a str, Output = &'a str> { + Regex(regex::Regex::new(pattern).unwrap()) + } +} + #[cfg(test)] mod test { use super::*; @@ -1016,4 +1045,17 @@ mod test { .check_finished(it) .unwrap(); } + + #[test] + fn test_regex_parser() { + let it = InputIter::new("abc 123"); + + match crate::str::regex("[abc]+").parse(it) { + Ok((rest, output)) => { + assert_eq!(output, "abc"); + assert_eq!(rest.rest(), " 123"); + } + _ => panic!(), + } + } } -- cgit v1.2.3