proclet/
token.rs

1use crate::{TokenStream, TokenTree};
2
3/// Trait for converting an object into its token representation.
4pub trait IntoTokens<T: TokenTree> {
5    /// Convert this object into an iterator of tokens representing the object.
6    fn into_tokens(self) -> impl Iterator<Item = T>;
7}
8
9/// Trait for getting the token representation of an object.
10pub trait ToTokens<T: TokenTree> {
11    /// Get an iterator of tokens representing this object.
12    fn to_tokens(&self) -> impl Iterator<Item = T> + '_;
13}
14
15impl<T: TokenTree, X: IntoTokens<T> + Clone> ToTokens<T> for X {
16    #[inline]
17    fn to_tokens(&self) -> impl Iterator<Item = T> {
18        self.clone().into_tokens()
19    }
20}
21
22impl<T: TokenTree, X: IntoTokens<T>> IntoTokens<T> for Option<X> {
23    #[inline]
24    fn into_tokens(self) -> impl Iterator<Item = T> {
25        self.into_iter().flat_map(|x| x.into_tokens())
26    }
27}
28
29/// Methods for making or extending a `TokenStream` with a representation of this object.
30pub trait ToTokenStream<T: TokenStream> {
31    /// Extend the given `TokenStream` with a representation of this object.
32    fn extend_token_stream(&self, token_stream: &mut T);
33
34    /// Make a new `TokenStream` with a representation of this object.
35    #[inline]
36    fn into_token_stream(self) -> T
37    where
38        Self: Sized,
39    {
40        let mut ts = T::new();
41        self.extend_token_stream(&mut ts);
42        ts
43    }
44
45    /// Make a new `TokenStream` with a representation of this object.
46    #[inline]
47    fn to_token_stream(&self) -> T {
48        let mut ts = T::new();
49        self.extend_token_stream(&mut ts);
50        ts
51    }
52}
53
54impl<T: TokenStream, X: ToTokenStream<T>> ToTokenStream<T> for [X] {
55    #[inline]
56    fn extend_token_stream(&self, token_stream: &mut T) {
57        for i in self {
58            i.extend_token_stream(token_stream);
59        }
60    }
61}
62
63impl<T: TokenStream, X: ToTokenStream<T>> ToTokenStream<T> for Option<X> {
64    #[inline]
65    fn extend_token_stream(&self, token_stream: &mut T) {
66        if let Some(x) = self {
67            x.extend_token_stream(token_stream);
68        }
69    }
70}
71
72impl<T: TokenTree, T0: IntoTokens<T>, T1: IntoTokens<T>> IntoTokens<T> for (T0, T1) {
73    #[inline]
74    fn into_tokens(self) -> impl Iterator<Item = T>
75    where
76        Self: Sized,
77    {
78        self.0.into_tokens().chain(self.1.into_tokens())
79    }
80}