ext.rs 2.7 KB

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