Skip to content

Instantly share code, notes, and snippets.

@tomalexander
Created March 15, 2017 06:31
Show Gist options
  • Save tomalexander/f6ffbc690b288f4c0b0aef98ebfaf686 to your computer and use it in GitHub Desktop.
Save tomalexander/f6ffbc690b288f4c0b0aef98ebfaf686 to your computer and use it in GitHub Desktop.
take_until_parser_matches
#[macro_use]
extern crate nom;
use nom::{IResult, line_ending, Needed, Slice, InputLength};
use std::str;
macro_rules! take_until_parser_matches(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::Slice;
let input = $i;
let input_length = input.input_len();
if input_length == 0 {
$crate::IResult::Incomplete($crate::Needed::Size(1))
} else {
let mut ind = 0;
for _ind in 0..input_length {
ind = _ind;
match $submac!(input.slice(ind..), $($args)*) {
$crate::IResult::Done(_, _) => break,
$crate::IResult::Error(_) => (),
$crate::IResult::Incomplete(_) => (),
}
}
$crate::IResult::Done(input.slice(ind..), input.slice(..ind))
}
}
);
($i:expr, $f:expr) => (
take_until_parser_matches!($i, call!($f));
);
);
named!(end <&[u8], std::vec::Vec<&str>>,
do_parse!(
body: many1!(map_res!(tag!("b"), str::from_utf8)) >>
alt!(eof!() | line_ending) >>
(body)
)
);
named!(tag_test <&[u8], (&str, std::vec::Vec<&str>)>,
do_parse!(
a: map_res!(take_until_parser_matches!(end), str::from_utf8) >>
b: end >>
(a, b)
)
);
pub fn main() {
let testinp = &b"aaaaaabaaabbbb\n"[..];
let res = tag_test(testinp);
match res {
IResult::Done(i, o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
IResult::Error(e) => println!("error {:?}", e),
IResult::Incomplete(_) => println!("incomplete")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment