macros_utils/
lib.rs

1mod error;
2mod parse;
3mod parsers;
4mod pattern;
5mod repr;
6mod tokens;
7
8use std::collections::VecDeque;
9
10pub use error::{MacrosError, ParseError, ParseErrorKind};
11pub use lazy_static::lazy_static;
12pub use parse::Parse;
13pub use pattern::{ParserInput, Pattern};
14use proc_macro2::TokenStream;
15pub use proc_macro2::{Spacing, Span};
16use quote::ToTokens;
17pub use repr::Repr;
18pub use tokens::{Delimiter, LiteralKind, Token};
19
20/// A stream of tokens.
21#[derive(Clone, Debug, PartialEq, Eq)]
22pub struct MacroStream {
23    stream: VecDeque<Token>,
24    popped: usize,
25}
26
27/// Type alias for the result of parsing to a `MacroStream`.
28pub type ParseResult<T> = std::result::Result<T, ParseError>;
29
30/// A match of a `Pattern`.
31#[derive(Clone, Debug)]
32pub enum Match {
33    One(Token),
34    Many(Vec<Match>),
35    None,
36}
37
38impl MacroStream {
39    /// Create a new empty `MacroStream`.
40    pub fn new() -> Self {
41        Self {
42            stream: VecDeque::new(),
43            popped: 0,
44        }
45    }
46
47    /// Determine how many tokens have been popped from the stream.
48    pub fn popped(&self) -> usize {
49        self.popped
50    }
51
52    /// Create a `MacroStream` from a `proc_macro2::TokenStream`.
53    pub fn from_tokens(stream: TokenStream) -> ParseResult<Self> {
54        let mut tokens = VecDeque::new();
55        for i in stream.into_iter() {
56            tokens.push_back(i);
57        }
58        let mut stream = VecDeque::new();
59        while !tokens.is_empty() {
60            stream.push_back(Token::from_tokens(&mut tokens)?);
61        }
62        Ok(Self { stream, popped: 0 })
63    }
64
65    /// Pop a token from the stream.
66    pub fn pop(&mut self) -> Option<Token> {
67        self.stream.pop_front()
68    }
69
70    /// Peek at the next token in the stream.
71    pub fn peek(&self) -> Option<&Token> {
72        self.peek_at(0)
73    }
74
75    /// Peek at the token at the given index in the stream.
76    pub fn peek_at(&self, i: usize) -> Option<&Token> {
77        self.stream.get(i)
78    }
79
80    /// Parse the stream into a type.
81    pub fn parse<T>(&mut self) -> Result<T, MacrosError>
82    where
83        T: Parse,
84    {
85        T::parse(self)
86    }
87
88    /// Determine if the stream is empty.
89    pub fn is_empty(&self) -> bool {
90        self.stream.is_empty()
91    }
92
93    /// Pop a token from the stream, or return an error if the stream is empty.
94    pub fn pop_or_err(&mut self) -> Result<Token, ParseError> {
95        self.pop()
96            .ok_or_else(|| {
97                ParseError::call_site(ParseErrorKind::UnexpectedEndOfInput("".to_string()))
98            })
99            .map(|i| {
100                self.popped += 1;
101                i
102            })
103    }
104
105    /// Peek at the next token in the stream, or return an error if the stream is empty.
106    pub fn peek_or_err(&self) -> Result<&Token, ParseError> {
107        self.peek().ok_or_else(|| {
108            ParseError::call_site(ParseErrorKind::UnexpectedEndOfInput("".to_string()))
109        })
110    }
111
112    /// Push a token to the front of the stream.
113    pub fn push_front(&mut self, token: Token) {
114        self.stream.push_front(token)
115    }
116
117    /// Push a token to the back of the stream.
118    pub fn push_back(&mut self, token: Token) {
119        self.stream.push_back(token)
120    }
121
122    /// Get the length of the stream.
123    pub fn len(&self) -> usize {
124        self.stream.len()
125    }
126
127    /// Fork the stream (clone the stream and reset the popped count).
128    pub fn fork(&self) -> Self {
129        Self {
130            stream: self.stream.clone(),
131            popped: 0,
132        }
133    }
134
135    /// Pop a number of tokens from the stream.
136    pub fn pop_many(&mut self, p: usize) {
137        for _ in 0..p {
138            self.pop().unwrap();
139        }
140    }
141}
142
143impl From<TokenStream> for MacroStream {
144    fn from(stream: TokenStream) -> Self {
145        Self::from_tokens(stream).unwrap()
146    }
147}
148
149impl Default for MacroStream {
150    fn default() -> Self {
151        Self::new()
152    }
153}
154
155impl ToTokens for MacroStream {
156    fn to_tokens(&self, tokens: &mut TokenStream) {
157        for i in &self.stream {
158            i.to_tokens(tokens);
159        }
160    }
161}
162
163/// A shortcut for `proc_macro2::Span::call_site()`.
164#[inline(always)]
165pub fn call_site() -> Span {
166    Span::call_site()
167}
168
169/// The trait for the output of a parser created by the `parser!` macro.
170pub trait ParserOutput {
171    fn set_match(&mut self, k: &str, m: Match);
172    fn name() -> &'static str;
173}