79 lines
2.4 KiB
Rust
79 lines
2.4 KiB
Rust
use crate::error::{Error, Result};
|
|
use crate::iter::Iter;
|
|
use proc_macro::{Delimiter, Group, Ident, Literal, Span, TokenTree};
|
|
|
|
pub fn parse_punct(iter: Iter, ch: char) -> Result<()> {
|
|
match iter.next() {
|
|
Some(TokenTree::Punct(ref punct)) if punct.as_char() == ch => Ok(()),
|
|
unexpected => {
|
|
let span = unexpected
|
|
.as_ref()
|
|
.map_or_else(Span::call_site, TokenTree::span);
|
|
Err(Error::new(span, format!("expected `{}`", ch)))
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn parse_optional_punct(iter: Iter, ch: char) -> Option<()> {
|
|
match iter.peek() {
|
|
Some(TokenTree::Punct(punct)) if punct.as_char() == ch => iter.next().map(drop),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn parse_optional_keyword(iter: Iter, keyword: &str) -> Option<Span> {
|
|
match iter.peek() {
|
|
Some(TokenTree::Ident(ident)) if ident.to_string() == keyword => {
|
|
Some(iter.next().unwrap().span())
|
|
}
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn parse_literal(iter: Iter) -> Result<Literal> {
|
|
match iter.next() {
|
|
Some(TokenTree::Literal(literal)) => Ok(literal),
|
|
unexpected => {
|
|
let span = unexpected
|
|
.as_ref()
|
|
.map_or_else(Span::call_site, TokenTree::span);
|
|
Err(Error::new(span, "expected literal"))
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn parse_paren(introducer: &Ident, iter: Iter) -> Result<Group> {
|
|
match iter.peek() {
|
|
Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => {
|
|
match iter.next() {
|
|
Some(TokenTree::Group(group)) => Ok(group),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
Some(unexpected) => Err(Error::new(unexpected.span(), "expected `(`")),
|
|
None => Err(Error::new(
|
|
introducer.span(),
|
|
format!("expected `(` after `{}`", introducer),
|
|
)),
|
|
}
|
|
}
|
|
|
|
pub fn parse_optional_paren(iter: Iter) -> Option<Group> {
|
|
match iter.peek() {
|
|
Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => {
|
|
match iter.next() {
|
|
Some(TokenTree::Group(group)) => Some(group),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn parse_end(iter: Iter) -> Result<()> {
|
|
match iter.next() {
|
|
None => Ok(()),
|
|
Some(unexpected) => Err(Error::new(unexpected.span(), "unexpected token")),
|
|
}
|
|
}
|