diff --git a/.gitignore b/.gitignore index ea8c4bf..5c37022 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/expand.rs diff --git a/src/cmd.rs b/src/cmd.rs index fe5a7b1..9626ad2 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -1,5 +1,10 @@ use quote::{quote, ToTokens}; -use syn::{braced, bracketed, parse::Parse, punctuated::Punctuated, token, Token}; +use syn::{ + braced, bracketed, + parse::{discouraged::Speculative, Parse}, + punctuated::Punctuated, + token, Token, +}; pub struct Command { program: Value, @@ -376,15 +381,23 @@ impl Parse for Value { fn parse(input: syn::parse::ParseStream) -> syn::Result { let expr_fork = input.fork(); expr_fork - .parse::() - .and_then(|_| input.parse().map(Self::Expr)) - .or_else(|_| { - let ident_fork = input.fork(); - ident_fork - .parse::() - .and_then(|_| input.parse().map(Self::Ident)) + .parse() + .map(|expr| { + input.advance_to(&expr_fork); + Self::Expr(expr) + }) + .or_else(|_| { + if input.peek(syn::Ident) { + input.parse().map(Self::Ident) + } else if input.peek(syn::Lit) { + input.parse().map(Self::Lit) + } else { + Err(syn::Error::new( + input.span(), + "Expected an expression, ident, or literal", + )) + } }) - .or_else(|_| input.parse().map(Self::Lit)) } }