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