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)?);
|
||||
}
|
||||
|
||||
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 TokenTree::Ident(ident) = tt {
|
||||
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() {
|
||||
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 TokenTree::Punct(p) = tt {
|
||||
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> {
|
||||
@ -91,11 +96,19 @@ pub fn need_group(tokens: &mut TokenIter, delimiter: Delimiter) -> Result<Group,
|
||||
pub fn match_colon(tokens: &mut TokenIter) -> Result<(), Error> {
|
||||
match tokens.next() {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
match tokens.next() {
|
||||
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(())
|
||||
}
|
||||
|
||||
pub fn need_hyphenated_name(tokens: &mut TokenIter) -> Result<syn::LitStr, Error> {
|
||||
let start = need_ident(&mut *tokens)?;
|
||||
pub fn need_hyphenated_name(span: Span, tokens: &mut TokenIter) -> Result<syn::LitStr, Error> {
|
||||
let start = need_ident(span, &mut *tokens)?;
|
||||
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> {
|
||||
if tokens.peek().is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
let span = match tokens.peek() {
|
||||
Some(ref val) => val.span(),
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let key = need_ident_or_string(&mut *tokens)?;
|
||||
match_colon(&mut *tokens)?;
|
||||
match_colon2(span, &mut *tokens)?;
|
||||
Ok(Some(key))
|
||||
}
|
||||
|
||||
|
@ -14,23 +14,26 @@ pub fn router_macro(input: TokenStream) -> Result<TokenStream, Error> {
|
||||
let mut out = TokenStream::new();
|
||||
|
||||
loop {
|
||||
if input.peek().is_none() {
|
||||
break;
|
||||
}
|
||||
let mut at_span = match input.peek() {
|
||||
Some(ref val) => val.span(),
|
||||
None => break,
|
||||
};
|
||||
|
||||
let public = optional_visibility(&mut input)?;
|
||||
|
||||
match_keyword(&mut input, "static")?;
|
||||
let router_name = need_ident(&mut input)?;
|
||||
at_span = match_keyword(at_span, &mut input, "static")?;
|
||||
let router_name = need_ident(at_span, &mut input)?;
|
||||
|
||||
match_colon(&mut input)?;
|
||||
match_keyword(&mut input, "Router")?;
|
||||
match_punct(&mut input, '<')?;
|
||||
let body_type = need_ident(&mut input)?;
|
||||
match_punct(&mut input, '>')?;
|
||||
at_span = match_colon2(router_name.span(), &mut input)?;
|
||||
at_span = match_keyword(at_span, &mut input, "Router")?;
|
||||
at_span = match_punct(at_span, &mut input, '<')?;
|
||||
let body_type = need_ident(at_span, &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 _ = at_span;
|
||||
at_span = content.span();
|
||||
|
||||
let router = parse_router(content.stream().into_iter().peekable())?;
|
||||
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);
|
||||
|
||||
match_punct(&mut input, ';')?;
|
||||
match_punct(at_span, &mut input, ';')?;
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
@ -270,7 +273,7 @@ fn parse_router(mut input: TokenIter) -> Result<Router, Error> {
|
||||
loop {
|
||||
match parse_entry_key(&mut input)? {
|
||||
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() {
|
||||
"GET" => &mut router.get,
|
||||
@ -334,7 +337,10 @@ fn parse_path_name(tokens: &mut TokenIter) -> Result<Path, Error> {
|
||||
if group.delimiter() != Delimiter::Brace {
|
||||
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);
|
||||
path.push(Component::Match(name));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user