summaryrefslogtreecommitdiff
path: root/src/enum_hack.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/enum_hack.rs')
-rw-r--r--src/enum_hack.rs123
1 files changed, 74 insertions, 49 deletions
diff --git a/src/enum_hack.rs b/src/enum_hack.rs
index 626b265..36ab1ad 100644
--- a/src/enum_hack.rs
+++ b/src/enum_hack.rs
@@ -1,10 +1,7 @@
+use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
-
-use proc_macro2::{Ident, Span, TokenStream, TokenTree};
-use quote::quote;
-use syn::parse::{Parse, ParseStream, Result};
-use syn::{braced, parenthesized, parse_macro_input, Token};
+use std::iter::FromIterator;
pub fn wrap(output: TokenStream) -> TokenStream {
let mut hasher = DefaultHasher::default();
@@ -12,50 +9,78 @@ pub fn wrap(output: TokenStream) -> TokenStream {
let mangled_name = format!("_paste_{}", hasher.finish());
let ident = Ident::new(&mangled_name, Span::call_site());
- quote! {
- #[derive(paste::EnumHack)]
- enum #ident {
- Value = (stringify! {
- #output
- }, 0).1,
- }
- }
-}
-
-struct EnumHack {
- token_stream: TokenStream,
-}
-
-impl Parse for EnumHack {
- fn parse(input: ParseStream) -> Result<Self> {
- input.parse::<Token![enum]>()?;
- input.parse::<Ident>()?;
-
- let braces;
- braced!(braces in input);
- braces.parse::<Ident>()?;
- braces.parse::<Token![=]>()?;
-
- let parens;
- parenthesized!(parens in braces);
- parens.parse::<Ident>()?;
- parens.parse::<Token![!]>()?;
-
- let inner;
- braced!(inner in parens);
- let token_stream: TokenStream = inner.parse()?;
-
- parens.parse::<Token![,]>()?;
- parens.parse::<TokenTree>()?;
- braces.parse::<Token![.]>()?;
- braces.parse::<TokenTree>()?;
- braces.parse::<Token![,]>()?;
-
- Ok(EnumHack { token_stream })
- }
+ // #[derive(paste::EnumHack)]
+ // enum #ident {
+ // Value = (stringify! {
+ // #output
+ // }, 0).1,
+ // }
+ TokenStream::from_iter(vec![
+ TokenTree::Punct(Punct::new('#', Spacing::Alone)),
+ TokenTree::Group(Group::new(
+ Delimiter::Bracket,
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("derive", Span::call_site())),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("paste", Span::call_site())),
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("EnumHack", Span::call_site())),
+ ]),
+ )),
+ ]),
+ )),
+ TokenTree::Ident(Ident::new("enum", Span::call_site())),
+ TokenTree::Ident(ident),
+ TokenTree::Group(Group::new(
+ Delimiter::Brace,
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("Value", Span::call_site())),
+ TokenTree::Punct(Punct::new('=', Spacing::Alone)),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("stringify", Span::call_site())),
+ TokenTree::Punct(Punct::new('!', Spacing::Alone)),
+ TokenTree::Group(Group::new(Delimiter::Brace, output)),
+ TokenTree::Punct(Punct::new(',', Spacing::Alone)),
+ TokenTree::Literal(Literal::usize_unsuffixed(0)),
+ ]),
+ )),
+ TokenTree::Punct(Punct::new('.', Spacing::Alone)),
+ TokenTree::Literal(Literal::usize_unsuffixed(1)),
+ TokenTree::Punct(Punct::new(',', Spacing::Alone)),
+ ]),
+ )),
+ ])
}
-pub fn extract(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- let inner = parse_macro_input!(input as EnumHack);
- proc_macro::TokenStream::from(inner.token_stream)
+pub fn extract(input: TokenStream) -> TokenStream {
+ let mut tokens = input.into_iter();
+ let _ = tokens.next().expect("enum");
+ let _ = tokens.next().expect("#ident");
+ let mut braces = match tokens.next().expect("{...}") {
+ TokenTree::Group(group) => group.stream().into_iter(),
+ _ => unreachable!("{...}"),
+ };
+ let _ = braces.next().expect("Value");
+ let _ = braces.next().expect("=");
+ let mut parens = match braces.next().expect("(...)") {
+ TokenTree::Group(group) => group.stream().into_iter(),
+ _ => unreachable!("(...)"),
+ };
+ let _ = parens.next().expect("stringify");
+ let _ = parens.next().expect("!");
+ let token_stream = match parens.next().expect("{...}") {
+ TokenTree::Group(group) => group.stream(),
+ _ => unreachable!("{...}"),
+ };
+ let _ = parens.next().expect(",");
+ let _ = parens.next().expect("0");
+ let _ = braces.next().expect(".");
+ let _ = braces.next().expect("1");
+ let _ = braces.next().expect(",");
+ token_stream
}