| 1 | use super::ToTokens; |
| 2 | use core::iter; |
| 3 | use proc_macro2::{TokenStream, TokenTree}; |
| 4 | |
| 5 | /// TokenStream extension trait with methods for appending tokens. |
| 6 | /// |
| 7 | /// This trait is sealed and cannot be implemented outside of the `quote` crate. |
| 8 | pub trait TokenStreamExt: private::Sealed { |
| 9 | /// For use by `ToTokens` implementations. |
| 10 | /// |
| 11 | /// Appends the token specified to this list of tokens. |
| 12 | fn append<U>(&mut self, token: U) |
| 13 | where |
| 14 | U: Into<TokenTree>; |
| 15 | |
| 16 | /// For use by `ToTokens` implementations. |
| 17 | /// |
| 18 | /// ``` |
| 19 | /// # use quote::{quote, TokenStreamExt, ToTokens}; |
| 20 | /// # use proc_macro2::TokenStream; |
| 21 | /// # |
| 22 | /// struct X; |
| 23 | /// |
| 24 | /// impl ToTokens for X { |
| 25 | /// fn to_tokens(&self, tokens: &mut TokenStream) { |
| 26 | /// tokens.append_all(&[true, false]); |
| 27 | /// } |
| 28 | /// } |
| 29 | /// |
| 30 | /// let tokens = quote!(#X); |
| 31 | /// assert_eq!(tokens.to_string(), "true false" ); |
| 32 | /// ``` |
| 33 | fn append_all<I>(&mut self, iter: I) |
| 34 | where |
| 35 | I: IntoIterator, |
| 36 | I::Item: ToTokens; |
| 37 | |
| 38 | /// For use by `ToTokens` implementations. |
| 39 | /// |
| 40 | /// Appends all of the items in the iterator `I`, separated by the tokens |
| 41 | /// `U`. |
| 42 | fn append_separated<I, U>(&mut self, iter: I, op: U) |
| 43 | where |
| 44 | I: IntoIterator, |
| 45 | I::Item: ToTokens, |
| 46 | U: ToTokens; |
| 47 | |
| 48 | /// For use by `ToTokens` implementations. |
| 49 | /// |
| 50 | /// Appends all tokens in the iterator `I`, appending `U` after each |
| 51 | /// element, including after the last element of the iterator. |
| 52 | fn append_terminated<I, U>(&mut self, iter: I, term: U) |
| 53 | where |
| 54 | I: IntoIterator, |
| 55 | I::Item: ToTokens, |
| 56 | U: ToTokens; |
| 57 | } |
| 58 | |
| 59 | impl TokenStreamExt for TokenStream { |
| 60 | fn append<U>(&mut self, token: U) |
| 61 | where |
| 62 | U: Into<TokenTree>, |
| 63 | { |
| 64 | self.extend(iter::once(token.into())); |
| 65 | } |
| 66 | |
| 67 | fn append_all<I>(&mut self, iter: I) |
| 68 | where |
| 69 | I: IntoIterator, |
| 70 | I::Item: ToTokens, |
| 71 | { |
| 72 | for token in iter { |
| 73 | token.to_tokens(self); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | fn append_separated<I, U>(&mut self, iter: I, op: U) |
| 78 | where |
| 79 | I: IntoIterator, |
| 80 | I::Item: ToTokens, |
| 81 | U: ToTokens, |
| 82 | { |
| 83 | for (i, token) in iter.into_iter().enumerate() { |
| 84 | if i > 0 { |
| 85 | op.to_tokens(self); |
| 86 | } |
| 87 | token.to_tokens(self); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | fn append_terminated<I, U>(&mut self, iter: I, term: U) |
| 92 | where |
| 93 | I: IntoIterator, |
| 94 | I::Item: ToTokens, |
| 95 | U: ToTokens, |
| 96 | { |
| 97 | for token in iter { |
| 98 | token.to_tokens(self); |
| 99 | term.to_tokens(self); |
| 100 | } |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | mod private { |
| 105 | use proc_macro2::TokenStream; |
| 106 | |
| 107 | pub trait Sealed {} |
| 108 | |
| 109 | impl Sealed for TokenStream {} |
| 110 | } |
| 111 | |