use std::iter;
use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
pub(crate) trait ToTokens {
fn to_tokens(&self, tokens: &mut TokenStream);
fn to_token_stream(&self) -> TokenStream {
let mut tokens = TokenStream::new();
self.to_tokens(&mut tokens);
tokens
}
fn span(&self) -> (Span, Span) {
let tokens = self.to_token_stream();
let mut iter = tokens.into_iter().filter_map(|tt| {
let span = tt.span();
let debug = format!("{:?}", span);
if debug.ends_with("bytes(0..0)") { None } else { Some(span) }
});
let first = match iter.next() {
Some(span) => span,
None => return (Span::call_site(), Span::call_site()),
};
(first, iter.last().unwrap_or(first))
}
}
impl ToTokens for Ident {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(iter::once(TokenTree::Ident(self.clone())));
}
}
impl ToTokens for Punct {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(iter::once(TokenTree::Punct(self.clone())));
}
}
impl ToTokens for Literal {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(iter::once(TokenTree::Literal(self.clone())));
}
}
impl ToTokens for Group {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(iter::once(TokenTree::Group(self.clone())));
}
}
impl ToTokens for TokenTree {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(iter::once(self.clone()));
}
}
impl ToTokens for TokenStream {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(self.clone());
}
}
impl<T: ToTokens> ToTokens for Option<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
if let Some(t) = self {
T::to_tokens(t, tokens);
}
}
}
impl<T: ?Sized + ToTokens> ToTokens for &T {
fn to_tokens(&self, tokens: &mut TokenStream) {
T::to_tokens(self, tokens);
}
}
impl<T: ToTokens> ToTokens for [T] {
fn to_tokens(&self, tokens: &mut TokenStream) {
for t in self {
T::to_tokens(t, tokens);
}
}
}
impl<T: ToTokens> ToTokens for [(T, Option<Punct>)] {
fn to_tokens(&self, tokens: &mut TokenStream) {
for (t, p) in self {
T::to_tokens(t, tokens);
p.to_tokens(tokens);
}
}
}