use crate::parsers::helpers::not_found_restore;
use crate::result::{ParserResult, ParserResultError};
use crate::Reader;
pub fn end<C, Err>(reader: &mut Reader<Err, C>) -> ParserResult<(), Err> {
if reader.is_end() {
Ok(())
} else {
Err(ParserResultError::NotFound)
}
}
pub fn not_consume<'a, C, R, Err>(
mut parser: impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err> {
move |reader| {
let init_cursor = reader.save_cursor();
let result = parser(reader)?;
reader.restore(init_cursor);
Ok(result)
}
}
pub fn verify<'a, C, R, P, V, Err>(
mut parser: P,
mut verifier: V,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>
where
P: FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
V: FnMut(&R) -> bool,
{
not_found_restore(move |reader| {
let result = parser(reader)?;
if verifier(&result) {
Ok(result)
} else {
Err(ParserResultError::NotFound)
}
})
}
pub fn optional<'a, C, R, Err>(
mut parser: impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<Option<R>, Err> {
move |reader| match parser(reader) {
Ok(v) => Ok(Some(v)),
Err(ParserResultError::NotFound) => Ok(None),
Err(e) => Err(e),
}
}
pub fn optional_default<'a, C, R: Default, Err>(
mut parser: impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err> {
move |reader| match parser(reader) {
Ok(v) => Ok(v),
Err(ParserResultError::NotFound) => Ok(R::default()),
Err(e) => Err(e),
}
}
pub fn not<'a, C, R, Err>(
mut parser: impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<(), Err> {
move |reader| match parser(reader) {
Ok(_) => Err(ParserResultError::NotFound),
Err(ParserResultError::NotFound) => Ok(()),
Err(e) => Err(e),
}
}
pub fn all_consumed<'a, C, R, Err>(
mut parser: impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err>,
) -> impl FnMut(&mut Reader<'a, Err, C>) -> ParserResult<R, Err> {
move |reader| {
let result = parser(reader)?;
if reader.is_end() {
Ok(result)
} else {
Err(ParserResultError::NotFound)
}
}
}
#[cfg(test)]
mod test {
use crate::parsers::characters::ascii_alpha1;
use super::*;
#[test]
fn test_end() {
let mut reader = Reader::new("This is a test");
let result = end(&mut reader);
assert_eq!(result, Err(ParserResultError::NotFound));
let mut reader = Reader::new("");
let result = end(&mut reader);
assert_eq!(result, Ok(()));
}
#[test]
fn test_not_consume() {
let mut reader = Reader::new("This is a test");
let mut parser = not_consume(ascii_alpha1);
let result = parser(&mut reader);
assert_eq!(result, Ok("This"));
assert_eq!(reader.byte_offset(), 0);
}
#[test]
fn test_verify() {
let mut reader = Reader::new("This is a test");
let mut parser = verify(ascii_alpha1, |x| *x == "This");
let result = parser(&mut reader);
assert_eq!(result, Ok("This"));
let result = parser(&mut reader);
assert_eq!(result, Err(ParserResultError::NotFound));
}
#[test]
fn test_optional() {
let mut reader = Reader::new("This is a test");
let mut parser = optional(ascii_alpha1);
let result = parser(&mut reader);
assert_eq!(result, Ok(Some("This")));
let result = parser(&mut reader);
assert_eq!(result, Ok(None));
}
#[test]
fn test_optional_default() {
let mut reader = Reader::new("This is a test");
let mut parser = optional_default(ascii_alpha1);
let result = parser(&mut reader);
assert_eq!(result, Ok("This"));
let result = parser(&mut reader);
assert_eq!(result, Ok(""));
}
#[test]
fn test_not() {
let mut reader = Reader::new("This is a test");
let mut parser = not(ascii_alpha1);
let result = parser(&mut reader);
assert_eq!(result, Err(ParserResultError::NotFound));
let mut reader = Reader::new(" test2");
let result = parser(&mut reader);
assert_eq!(result, Ok(()));
}
#[test]
fn test_all_consumed() {
let mut reader = Reader::new("Test");
let mut parser = all_consumed(ascii_alpha1);
let result = parser(&mut reader);
assert_eq!(result, Ok("Test"));
let mut reader = Reader::new(" test2");
let result = parser(&mut reader);
assert_eq!(result, Err(ParserResultError::NotFound));
}
}