Skip to content

Instantly share code, notes, and snippets.

@detly
Last active March 2, 2021 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save detly/1e03c0adcbdfc27eb1de9650519b923a to your computer and use it in GitHub Desktop.
Save detly/1e03c0adcbdfc27eb1de9650519b923a to your computer and use it in GitHub Desktop.
Nom example
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete;
use nom::sequence::preceded;
use nom::{error::ParseError, AsChar, IResult, InputIter, Parser, Slice};
use std::str::FromStr;
#[derive(Clone, Copy, PartialEq, Debug)]
enum Flip {
Heads,
Tails,
}
impl FromStr for Flip {
type Err = &'static str;
fn from_str(text: &str) -> Result<Self, Self::Err> {
match text {
"HEADS" => Ok(Flip::Heads),
"TAILS" => Ok(Flip::Tails),
_ => Err("Invalid result"),
}
}
}
type ParseResult<'a, T> = IResult<&'a str, T>;
fn after_slash<I, O, F, E: ParseError<I>>(parser: F) -> impl FnMut(I) -> IResult<I, O, E>
where
F: Parser<I, O, E>,
I: Slice<std::ops::RangeFrom<usize>> + InputIter,
<I as InputIter>::Item: AsChar,
{
preceded(complete::char('/'), parser)
}
fn main() {
const INPUT: &str = "/HEADS/TAILS";
let result: ParseResult<Flip> =
tuple((after_slash(<&str>::parse_to), after_slash(<&str>::parse_to)))(INPUT);
// Current best working alternative:
// tuple(( after_slash( alt( tag("HEADS"), tag("TAILS") ) repeat a million times
println!("Got: {:?}", result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment