Skip to content

Instantly share code, notes, and snippets.

@ian-p-cooke
Created July 6, 2018 14:14
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 ian-p-cooke/dbe83813a08d110548918b33754d5ee9 to your computer and use it in GitHub Desktop.
Save ian-p-cooke/dbe83813a08d110548918b33754d5ee9 to your computer and use it in GitHub Desktop.
example of parsers abstracting over multiple nom input types
#[macro_use]
extern crate nom;
use nom::types::{CompleteByteSlice, CompleteStr};
use nom::{digit, recognize_float, space, IResult};
use std::str;
pub trait NomInput<'a, U: nom::AsChar>:
Clone
+ nom::Slice<std::ops::Range<usize>>
+ nom::Slice<std::ops::RangeFrom<usize>>
+ nom::Slice<std::ops::RangeTo<usize>>
+ nom::Offset
+ nom::InputIter<Item = U, RawItem = U>
+ nom::AtEof
+ nom::InputLength
+ nom::InputTake
+ nom::InputTakeAtPosition<Item = U>
+ nom::Compare<&'a str>
{
}
impl<'a> NomInput<'a, u8> for &'a [u8] {}
impl<'a> NomInput<'a, char> for &'a str {}
impl<'a> NomInput<'a, u8> for CompleteByteSlice<'a> {}
impl<'a> NomInput<'a, char> for CompleteStr<'a> {}
#[allow(unused_imports)]
pub fn floating_point<'a, I, O, U>(input: I) -> IResult<I, O>
where
I: NomInput<'a, U> + nom::ParseTo<O>,
U: nom::AsChar,
{
flat_map!(input, call!(recognize_float), parse_to!(O))
}
#[allow(unused_imports)]
pub fn integer<'a, I, O, U>(input: I) -> IResult<I, O>
where
I: NomInput<'a, U> + nom::ParseTo<O>,
U: nom::AsChar,
{
flat_map!(input, call!(digit), parse_to!(O))
}
#[allow(unused_imports)]
pub fn doubles_and_int<'a, I, U>(input: I) -> IResult<I, (f64, i64)>
where
I: NomInput<'a, U> + nom::ParseTo<f64> + nom::ParseTo<i64>,
U: Clone + nom::AsChar,
{
do_parse!(
input,
tag!("DI") >> d: floating_point >> space >> n: integer >> (d, n)
)
}
fn main() {
let input = "DI3.14 42";
let input_cs = CompleteStr(input);
let input_b = input.as_bytes();
let input_cbs = CompleteByteSlice(input_b);
println!("{:?}", doubles_and_int(input));
println!("{:?}", doubles_and_int(input_b));
println!("{:?}", doubles_and_int(input_cs));
println!("{:?}", doubles_and_int(input_cbs));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment