| 1 | use std::num::NonZeroU16; |
| 2 | |
| 3 | use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree}; |
| 4 | |
| 5 | /// Turn a type into a [`TokenStream`]. |
| 6 | pub(crate) trait ToTokenStream: Sized { |
| 7 | fn append_to(self, ts: &mut TokenStream); |
| 8 | } |
| 9 | |
| 10 | pub(crate) trait ToTokenTree: Sized { |
| 11 | fn into_token_tree(self) -> TokenTree; |
| 12 | } |
| 13 | |
| 14 | impl<T: ToTokenTree> ToTokenStream for T { |
| 15 | fn append_to(self, ts: &mut TokenStream) { |
| 16 | ts.extend([self.into_token_tree()]) |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | impl ToTokenTree for bool { |
| 21 | fn into_token_tree(self) -> TokenTree { |
| 22 | let lit: &'static str = if self { "true" } else { "false" }; |
| 23 | TokenTree::Ident(Ident::new(string:lit, Span::mixed_site())) |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | impl ToTokenStream for TokenStream { |
| 28 | fn append_to(self, ts: &mut TokenStream) { |
| 29 | ts.extend(self) |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | impl ToTokenTree for TokenTree { |
| 34 | fn into_token_tree(self) -> TokenTree { |
| 35 | self |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | impl ToTokenTree for &str { |
| 40 | fn into_token_tree(self) -> TokenTree { |
| 41 | TokenTree::Literal(Literal::string(self)) |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | impl ToTokenTree for NonZeroU16 { |
| 46 | fn into_token_tree(self) -> TokenTree { |
| 47 | quote_group! {{ |
| 48 | unsafe { ::core::num::NonZeroU16::new_unchecked(#(self.get())) } |
| 49 | }} |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | macro_rules! impl_for_tree_types { |
| 54 | ($($type:ty)*) => {$( |
| 55 | impl ToTokenTree for $type { |
| 56 | fn into_token_tree(self) -> TokenTree { |
| 57 | TokenTree::from(self) |
| 58 | } |
| 59 | } |
| 60 | )*}; |
| 61 | } |
| 62 | impl_for_tree_types![Ident Literal Group Punct]; |
| 63 | |
| 64 | macro_rules! impl_for_int { |
| 65 | ($($type:ty => $method:ident)*) => {$( |
| 66 | impl ToTokenTree for $type { |
| 67 | fn into_token_tree(self) -> TokenTree { |
| 68 | TokenTree::from(Literal::$method(self)) |
| 69 | } |
| 70 | } |
| 71 | )*}; |
| 72 | } |
| 73 | impl_for_int! { |
| 74 | i8 => i8_unsuffixed |
| 75 | u8 => u8_unsuffixed |
| 76 | u16 => u16_unsuffixed |
| 77 | i32 => i32_unsuffixed |
| 78 | u32 => u32_unsuffixed |
| 79 | } |
| 80 | |