1use crate::error::{Error, Result};
2use crate::iter::Iter;
3use proc_macro::{Delimiter, Group, Ident, Literal, Span, TokenTree};
4
5pub fn parse_punct(iter: Iter, ch: char) -> Result<()> {
6 match iter.next() {
7 Some(TokenTree::Punct(ref punct: &Punct)) if punct.as_char() == ch => Ok(()),
8 unexpected: Option => {
9 let span: Span = unexpected
10 .as_ref()
11 .map_or_else(default:Span::call_site, f:TokenTree::span);
12 Err(Error::new(span, msg:format!("expected `{}`", ch)))
13 }
14 }
15}
16
17pub fn parse_optional_punct(iter: Iter, ch: char) -> Option<()> {
18 match iter.peek() {
19 Some(TokenTree::Punct(punct: &Punct)) if punct.as_char() == ch => iter.next().map(drop),
20 _ => None,
21 }
22}
23
24pub fn parse_optional_keyword(iter: Iter, keyword: &str) -> Option<Span> {
25 match iter.peek() {
26 Some(TokenTree::Ident(ident: &Ident)) if ident.to_string() == keyword => {
27 Some(iter.next().unwrap().span())
28 }
29 _ => None,
30 }
31}
32
33pub fn parse_literal(iter: Iter) -> Result<Literal> {
34 match iter.next() {
35 Some(TokenTree::Literal(literal: Literal)) => Ok(literal),
36 unexpected: Option => {
37 let span: Span = unexpected
38 .as_ref()
39 .map_or_else(default:Span::call_site, f:TokenTree::span);
40 Err(Error::new(span, msg:"expected literal"))
41 }
42 }
43}
44
45pub fn parse_paren(introducer: &Ident, iter: Iter) -> Result<Group> {
46 match iter.peek() {
47 Some(TokenTree::Group(group: &Group)) if group.delimiter() == Delimiter::Parenthesis => {
48 match iter.next() {
49 Some(TokenTree::Group(group: Group)) => Ok(group),
50 _ => unreachable!(),
51 }
52 }
53 Some(unexpected: &TokenTree) => Err(Error::new(unexpected.span(), msg:"expected `(`")),
54 None => Err(Error::new(
55 introducer.span(),
56 msg:format!("expected `(` after `{}`", introducer),
57 )),
58 }
59}
60
61pub fn parse_optional_paren(iter: Iter) -> Option<Group> {
62 match iter.peek() {
63 Some(TokenTree::Group(group: &Group)) if group.delimiter() == Delimiter::Parenthesis => {
64 match iter.next() {
65 Some(TokenTree::Group(group: Group)) => Some(group),
66 _ => unreachable!(),
67 }
68 }
69 _ => None,
70 }
71}
72
73pub fn parse_end(iter: Iter) -> Result<()> {
74 match iter.next() {
75 None => Ok(()),
76 Some(unexpected: TokenTree) => Err(Error::new(unexpected.span(), msg:"unexpected token")),
77 }
78}
79