Skip to content

Commit 20a87ca

Browse files
committed
Add support for multiple generic input types
1 parent 2728bda commit 20a87ca

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "nom-parse-macros"
33
description = "Procedural macros for generating parser functions for the nom libary"
4-
version = "0.1.0"
4+
version = "0.1.1"
55
license = "MIT/Apache-2.0"
66
keywords = ["nom", "parser", "parsable"]
77
categories = ["parsing"]

src/lib.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ fn generate_struct_parser(attrs: TokenStream, mut object: ItemStruct) -> TokenSt
4040
let expression_names = fields.get_expression_names();
4141
let derived_expressions = fields.get_derived_expressions();
4242
let create_expr = fields.create_instance_expr(None);
43+
let where_clause = generate_where_clause();
4344

4445
let tokens = quote! {
4546
#object
4647

47-
impl nom_parse_trait::ParseFrom<&str> for #name {
48-
fn parse(input: &str) -> nom::IResult<&str, Self> {
48+
impl<I> nom_parse_trait::ParseFrom<I> for #name
49+
#where_clause
50+
{
51+
fn parse(input: I) -> nom::IResult<I, Self> {
4952
use nom::*;
5053

5154
let (input, (#(#expression_names),*)) = #expression.parse(input)?;
@@ -145,15 +148,18 @@ pub fn parse_match(attrs: TokenStream, object: TokenStream) -> TokenStream {
145148
Err(e) => return e.to_compile_error().into(),
146149
};
147150
let name = object.ident.clone();
151+
let where_clause = generate_where_clause();
148152

149153
match parse_string_match(&fields, literal) {
150154
Ok(parts) => {
151155
let names: Vec<_> = fields.fields.iter().map(|field| field.get_name()).collect();
152156
let tokens = quote! {
153157
#object
154158

155-
impl nom_parse_trait::ParseFrom<&str> for #name {
156-
fn parse(input: &str) -> nom::IResult<&str, Self> {
159+
impl<I> nom_parse_trait::ParseFrom<I> for #name
160+
#where_clause
161+
{
162+
fn parse(input: I) -> nom::IResult<I, Self> {
157163
use nom::*;
158164

159165
let mut input = input;
@@ -168,3 +174,18 @@ pub fn parse_match(attrs: TokenStream, object: TokenStream) -> TokenStream {
168174
Err(e) => e.to_compile_error().into(),
169175
}
170176
}
177+
178+
fn generate_where_clause() -> proc_macro2::TokenStream {
179+
quote! {
180+
where
181+
I: Clone,
182+
I: nom::Slice<std::ops::RangeTo<usize>> + nom::Slice<std::ops::RangeFrom<usize>> + nom::Slice<std::ops::Range<usize>>,
183+
I: nom::InputTake + nom::InputLength + nom::Offset + nom::AsBytes,
184+
I: nom::InputIter,
185+
<I as nom::InputIter>::Item: nom::AsChar + Copy,
186+
<I as nom::InputIter>::IterElem: Clone,
187+
I: nom::InputTakeAtPosition,
188+
<I as nom::InputTakeAtPosition>::Item: nom::AsChar + Copy,
189+
I: for<'a> nom::Compare<&'a [u8]>,
190+
}
191+
}

tests/different_input_types.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use nom_parse_macros::parse_from;
2+
use nom_parse_trait::ParseFromExt;
3+
4+
#[parse_from(())]
5+
#[derive(Debug, PartialEq)]
6+
struct Test(i32);
7+
8+
#[test]
9+
pub fn from_str() {
10+
assert_eq!(Ok(Test(32)), Test::parse_complete("32"));
11+
}
12+
13+
#[test]
14+
pub fn from_bytes() {
15+
assert_eq!(Ok(Test(32)), Test::parse_complete(b"32".as_ref()));
16+
}

0 commit comments

Comments
 (0)