kefta_core/token/
stream.rs

1use std::iter::Peekable;
2use proc_macro2::token_stream::IntoIter as TokenStreamIter;
3use proc_macro2::{Span, TokenStream, TokenTree};
4use crate::error::KeftaTokenError;
5use crate::token::AttrTokenParse;
6
7pub struct AttrTokenStream {
8    last_span: Span,
9    tokens: Peekable<TokenStreamIter>,
10}
11
12
13impl AttrTokenStream {
14    pub fn new(stream: TokenStream) -> Self {
15        Self {
16            // not happy with this :(
17            last_span: match stream.clone().into_iter().last() {
18                None => Span::call_site(),
19                Some(TokenTree::Group(x)) => x.span(),
20                Some(TokenTree::Ident(x)) => x.span(),
21                Some(TokenTree::Punct(x)) => x.span(),
22                Some(TokenTree::Literal(x)) => x.span(),
23            },
24            tokens: stream.into_iter().peekable()
25        }
26    }
27
28    pub fn new_tree(tree: TokenTree) -> Self {
29        Self::new(TokenStream::from(tree))
30    }
31
32    pub fn next(&mut self) -> Option<TokenTree> {
33        self.tokens.next()
34    }
35
36    pub fn peek(&mut self) -> Option<&TokenTree> {
37        self.tokens.peek()
38    }
39
40    pub fn skip(&mut self) {
41        let _ = self.tokens.next();
42    }
43
44    pub fn parse<T: AttrTokenParse>(&mut self) -> Result<T, KeftaTokenError> {
45        T::parse(self)
46    }
47
48    pub fn has_tokens(&mut self) -> bool {
49        self.tokens.peek().is_some()
50    }
51
52    pub fn stream_span(&self) -> Span {
53        self.last_span.clone()
54    }
55}