Skip to content

Commit 58415ed

Browse files
committed
Improve handling of nom functions, where we know what parameters are expected to be parsers.
This way we can actually use string literals as shortcut for parsers, while still also being available normally for functions like "tag" or "one_of".
1 parent c6801a9 commit 58415ed

File tree

4 files changed

+223
-284
lines changed

4 files changed

+223
-284
lines changed

examples/basic_struct_with_members.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use nom_parse_macros::parse_from;
22
use nom_parse_trait::ParseFrom;
33

4-
#[parse_from(split = delimited(space0, ",", space0))]
4+
#[parse_from(split = tuple(space0, ",", space0))]
55
#[derive(Debug, PartialEq)]
66
struct NumberPair {
77
x: u32,

src/lib.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
mod settings;
1+
extern crate proc_macro;
22
mod fields;
33
mod nom_packages;
4+
mod settings;
45

5-
extern crate proc_macro;
66
use proc_macro::TokenStream;
77

8-
use quote::quote;
9-
use syn::ItemStruct;
108
use crate::fields::parse_fields;
119
use crate::settings::ParseSettings;
10+
use quote::quote;
11+
use syn::ItemStruct;
1212

1313
#[proc_macro_attribute]
1414
pub fn parse_from(attrs: TokenStream, object: TokenStream) -> TokenStream {
@@ -21,22 +21,26 @@ pub fn parse_from(attrs: TokenStream, object: TokenStream) -> TokenStream {
2121
let fields = parse_fields(&object.fields);
2222
let name = object.ident.clone();
2323

24-
let expressions = parse_settings.generate_parse_expressions(&fields);
25-
let names: Vec<_> = fields.iter().map(|field| field.get_name()).collect();
24+
parse_settings
25+
.generate_parse_expressions(&fields)
26+
.map(|expressions| {
27+
let names: Vec<_> = fields.iter().map(|field| field.get_name()).collect();
2628

27-
let tokens = quote! {
28-
#object
29+
let tokens = quote! {
30+
#object
2931

30-
impl nom_parse_trait::ParseFrom<&str> for #name {
31-
fn parse(input: &str) -> nom::IResult<&str, Self> {
32-
use nom::Parser;
32+
impl nom_parse_trait::ParseFrom<&str> for #name {
33+
fn parse(input: &str) -> nom::IResult<&str, Self> {
34+
use nom::Parser;
3335

34-
let mut input = input;
35-
#(#expressions)*
36-
Ok((input, Self { #(#names),* }))
37-
}
38-
}
39-
};
36+
let mut input = input;
37+
#(#expressions)*
38+
Ok((input, Self { #(#names),* }))
39+
}
40+
}
41+
};
4042

41-
tokens.into()
43+
tokens.into()
44+
})
45+
.unwrap_or_else(|e| e.to_compile_error().into())
4246
}

0 commit comments

Comments
 (0)