Mercurial > lbo > hg > rcombinators
changeset 9:7689ce15e914
primitives: Implement OneOf and string_of primitives
author | Lewin Bormann <lewin@lewin-bormann.info> |
---|---|
date | Sun, 02 Jun 2019 10:44:18 +0000 |
parents | 335ba6716c4e |
children | 61a0e5bc6f6c |
files | src/primitives.rs |
diffstat | 1 files changed, 39 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/primitives.rs Sun Jun 02 10:44:04 2019 +0000 +++ b/src/primitives.rs Sun Jun 02 10:44:18 2019 +0000 @@ -1,6 +1,10 @@ +use crate::combinators::{Repeat, RepeatSpec, Transform}; use crate::parser::{ParseError, ParseResult, Parser}; use crate::state::ParseState; +use std::collections::HashSet; +use std::iter::FromIterator; + pub struct StringParser(String); impl StringParser { @@ -75,6 +79,34 @@ } } +pub struct OneOf(HashSet<char>); + +impl OneOf { + pub fn new<S: AsRef<str>>(chars: S) -> OneOf { + OneOf(chars.as_ref().chars().collect()) + } +} + +impl Parser for OneOf { + type Result = char; + fn parse(&mut self, st: &mut ParseState<impl Iterator<Item = char>>) -> ParseResult<Self::Result> { + match st.peek() { + Some(c) if self.0.contains(&c) => { st.next(); Ok(c) }, + _ => Err(ParseError::Fail("char not matched", st.index())), + } + } +} + +/// A parser that parses a string consisting of characters `chars`. +fn string_of<S: AsRef<str>>(chars: S, rp: RepeatSpec) -> impl Parser<Result=String> { + let oo = OneOf::new(chars); + let rp = Repeat::new(oo, rp); + let make_string = |charvec: Vec<char>| { + Ok(String::from_iter(charvec.into_iter())) + }; + Transform::new(rp, make_string) +} + #[cfg(test)] mod tests { use super::*; @@ -96,4 +128,11 @@ assert_eq!(Ok(" ".to_string()), sp.parse(&mut s)); assert_eq!(Ok(353), ip.parse(&mut s)); } + + #[test] + fn test_string_of() { + let mut st = ParseState::new("aaabcxxzy"); + let mut p = string_of("abcd", RepeatSpec::Min(1)); + assert_eq!(Ok("aaabc".to_string()), p.parse(&mut st)); + } }