forked from Proxmox/proxmox
macro: improve error output
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
3a36ff78df
commit
ef13b38632
@ -50,33 +50,38 @@ pub fn optional_visibility(tokens: &mut TokenIter) -> Result<syn::Visibility, Er
|
|||||||
return Ok(parser.parse2(visibility)?);
|
return Ok(parser.parse2(visibility)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_keyword(tokens: &mut TokenIter, keyword: &'static str) -> Result<(), Error> {
|
pub fn match_keyword(
|
||||||
|
span: Span,
|
||||||
|
tokens: &mut TokenIter,
|
||||||
|
keyword: &'static str,
|
||||||
|
) -> Result<Span, Error> {
|
||||||
if let Some(tt) = tokens.next() {
|
if let Some(tt) = tokens.next() {
|
||||||
if let TokenTree::Ident(ident) = tt {
|
if let TokenTree::Ident(ident) = tt {
|
||||||
if ident.to_string() == keyword {
|
if ident.to_string() == keyword {
|
||||||
return Ok(());
|
return Ok(ident.span());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bail!("expected `{}` keyword", keyword);
|
c_bail!(span, "expected `{}` keyword", keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn need_ident(tokens: &mut TokenIter) -> Result<Ident, Error> {
|
pub fn need_ident(before: Span, tokens: &mut TokenIter) -> Result<Ident, Error> {
|
||||||
match tokens.next() {
|
match tokens.next() {
|
||||||
Some(TokenTree::Ident(ident)) => Ok(ident),
|
Some(TokenTree::Ident(ident)) => Ok(ident),
|
||||||
other => bail!("expected ident: {:?}", other),
|
Some(other) => c_bail!(other.span(), "expected ident"),
|
||||||
|
None => c_bail!(before, "expected ident after this expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_punct(tokens: &mut TokenIter, punct: char) -> Result<(), Error> {
|
pub fn match_punct(span: Span, tokens: &mut TokenIter, punct: char) -> Result<Span, Error> {
|
||||||
if let Some(tt) = tokens.next() {
|
if let Some(tt) = tokens.next() {
|
||||||
if let TokenTree::Punct(p) = tt {
|
if let TokenTree::Punct(p) = tt {
|
||||||
if p.as_char() == punct {
|
if p.as_char() == punct {
|
||||||
return Ok(());
|
return Ok(p.span());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bail!("expected `{}`", punct);
|
c_bail!(span, "expected `{}` after this expression", punct);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn need_group(tokens: &mut TokenIter, delimiter: Delimiter) -> Result<Group, Error> {
|
pub fn need_group(tokens: &mut TokenIter, delimiter: Delimiter) -> Result<Group, Error> {
|
||||||
@ -91,11 +96,19 @@ pub fn need_group(tokens: &mut TokenIter, delimiter: Delimiter) -> Result<Group,
|
|||||||
pub fn match_colon(tokens: &mut TokenIter) -> Result<(), Error> {
|
pub fn match_colon(tokens: &mut TokenIter) -> Result<(), Error> {
|
||||||
match tokens.next() {
|
match tokens.next() {
|
||||||
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ':' => Ok(()),
|
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ':' => Ok(()),
|
||||||
Some(other) => bail!("expected colon at {:?}", other.span()),
|
Some(other) => c_bail!(other.span(), "expected colon"),
|
||||||
None => bail!("colon expected"),
|
None => bail!("colon expected"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn match_colon2(span: Span, tokens: &mut TokenIter) -> Result<Span, Error> {
|
||||||
|
match tokens.next() {
|
||||||
|
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ':' => Ok(punct.span()),
|
||||||
|
Some(other) => c_bail!(other.span(), "expected colon"),
|
||||||
|
None => c_bail!(span, "colon expected following this expression"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn maybe_comma(tokens: &mut TokenIter) -> Result<bool, Error> {
|
pub fn maybe_comma(tokens: &mut TokenIter) -> Result<bool, Error> {
|
||||||
match tokens.next() {
|
match tokens.next() {
|
||||||
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => Ok(true),
|
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => Ok(true),
|
||||||
@ -119,8 +132,8 @@ pub fn comma_or_end(tokens: &mut TokenIter) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn need_hyphenated_name(tokens: &mut TokenIter) -> Result<syn::LitStr, Error> {
|
pub fn need_hyphenated_name(span: Span, tokens: &mut TokenIter) -> Result<syn::LitStr, Error> {
|
||||||
let start = need_ident(&mut *tokens)?;
|
let start = need_ident(span, &mut *tokens)?;
|
||||||
finish_hyphenated_name(&mut *tokens, start)
|
finish_hyphenated_name(&mut *tokens, start)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,12 +326,13 @@ pub fn parse_object(tokens: TokenStream) -> Result<Object, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_object_key(tokens: &mut TokenIter) -> Result<Option<Name>, Error> {
|
fn parse_object_key(tokens: &mut TokenIter) -> Result<Option<Name>, Error> {
|
||||||
if tokens.peek().is_none() {
|
let span = match tokens.peek() {
|
||||||
return Ok(None);
|
Some(ref val) => val.span(),
|
||||||
}
|
None => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
let key = need_ident_or_string(&mut *tokens)?;
|
let key = need_ident_or_string(&mut *tokens)?;
|
||||||
match_colon(&mut *tokens)?;
|
match_colon2(span, &mut *tokens)?;
|
||||||
Ok(Some(key))
|
Ok(Some(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,23 +14,26 @@ pub fn router_macro(input: TokenStream) -> Result<TokenStream, Error> {
|
|||||||
let mut out = TokenStream::new();
|
let mut out = TokenStream::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if input.peek().is_none() {
|
let mut at_span = match input.peek() {
|
||||||
break;
|
Some(ref val) => val.span(),
|
||||||
}
|
None => break,
|
||||||
|
};
|
||||||
|
|
||||||
let public = optional_visibility(&mut input)?;
|
let public = optional_visibility(&mut input)?;
|
||||||
|
|
||||||
match_keyword(&mut input, "static")?;
|
at_span = match_keyword(at_span, &mut input, "static")?;
|
||||||
let router_name = need_ident(&mut input)?;
|
let router_name = need_ident(at_span, &mut input)?;
|
||||||
|
|
||||||
match_colon(&mut input)?;
|
at_span = match_colon2(router_name.span(), &mut input)?;
|
||||||
match_keyword(&mut input, "Router")?;
|
at_span = match_keyword(at_span, &mut input, "Router")?;
|
||||||
match_punct(&mut input, '<')?;
|
at_span = match_punct(at_span, &mut input, '<')?;
|
||||||
let body_type = need_ident(&mut input)?;
|
let body_type = need_ident(at_span, &mut input)?;
|
||||||
match_punct(&mut input, '>')?;
|
at_span = match_punct(body_type.span(), &mut input, '>')?;
|
||||||
|
|
||||||
match_punct(&mut input, '=')?;
|
at_span = match_punct(at_span, &mut input, '=')?;
|
||||||
let content = need_group(&mut input, Delimiter::Brace)?;
|
let content = need_group(&mut input, Delimiter::Brace)?;
|
||||||
|
let _ = at_span;
|
||||||
|
at_span = content.span();
|
||||||
|
|
||||||
let router = parse_router(content.stream().into_iter().peekable())?;
|
let router = parse_router(content.stream().into_iter().peekable())?;
|
||||||
let router = router.into_token_stream(&body_type, Some((router_name, public)));
|
let router = router.into_token_stream(&body_type, Some((router_name, public)));
|
||||||
@ -39,7 +42,7 @@ pub fn router_macro(input: TokenStream) -> Result<TokenStream, Error> {
|
|||||||
|
|
||||||
out.extend(router);
|
out.extend(router);
|
||||||
|
|
||||||
match_punct(&mut input, ';')?;
|
match_punct(at_span, &mut input, ';')?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
@ -270,7 +273,7 @@ fn parse_router(mut input: TokenIter) -> Result<Router, Error> {
|
|||||||
loop {
|
loop {
|
||||||
match parse_entry_key(&mut input)? {
|
match parse_entry_key(&mut input)? {
|
||||||
Some(Entry::Method(name)) => {
|
Some(Entry::Method(name)) => {
|
||||||
let function = need_ident(&mut input)?;
|
let function = need_ident(name.span(), &mut input)?;
|
||||||
|
|
||||||
let method_ptr = match name.to_string().as_str() {
|
let method_ptr = match name.to_string().as_str() {
|
||||||
"GET" => &mut router.get,
|
"GET" => &mut router.get,
|
||||||
@ -334,7 +337,10 @@ fn parse_path_name(tokens: &mut TokenIter) -> Result<Path, Error> {
|
|||||||
if group.delimiter() != Delimiter::Brace {
|
if group.delimiter() != Delimiter::Brace {
|
||||||
bail!("invalid path component: {:?}", group);
|
bail!("invalid path component: {:?}", group);
|
||||||
}
|
}
|
||||||
let name = need_hyphenated_name(&mut group.stream().into_iter().peekable())?;
|
let name = need_hyphenated_name(
|
||||||
|
group.span(),
|
||||||
|
&mut group.stream().into_iter().peekable(),
|
||||||
|
)?;
|
||||||
push_component(&mut path, &mut component, &mut span);
|
push_component(&mut path, &mut component, &mut span);
|
||||||
path.push(Component::Match(name));
|
path.push(Component::Match(name));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user