|
1 | | -use proc_macro2::TokenStream; |
| 1 | +use proc_macro2::{TokenStream,Ident}; |
2 | 2 | use quote::quote;
|
3 | 3 | use syn::ItemTrait;
|
4 | 4 |
|
| 5 | +/// 対象: トレイト |
| 6 | +/// 動作: 文脈導入用の宣言型マクロを生成 |
5 | 7 | pub fn proc_macro_impl(_args: TokenStream, ast: ItemTrait) -> TokenStream {
|
| 8 | + let trait_name = &ast.ident; |
| 9 | + let macro_ident = as_macro_ident(trait_name); |
| 10 | + |
6 | 11 | quote! {
|
7 | 12 | #ast
|
8 | 13 |
|
9 | | - macro_rules! hello { |
10 | | - () => { |
11 | | - println!("Hello!"); |
12 | | - }; |
| 14 | + macro_rules! #macro_ident { |
| 15 | + ($($body:tt)*) => {{ |
| 16 | + fn __mymodifier_callee() { |
| 17 | + $($body)* |
| 18 | + } |
| 19 | + __mymodifier_callee(); |
| 20 | + }}; |
13 | 21 | }
|
14 | 22 | }
|
15 | 23 | }
|
| 24 | + |
| 25 | +fn as_macro_ident(ident: &Ident) -> TokenStream { |
| 26 | + let mut result = String::new(); |
| 27 | + for c in ident.to_string().chars() { |
| 28 | + if c.is_uppercase() { |
| 29 | + result.push('_'); |
| 30 | + result.push(c.to_ascii_lowercase()); |
| 31 | + } else { |
| 32 | + result.push(c); |
| 33 | + } |
| 34 | + } |
| 35 | + |
| 36 | + let result = if result.starts_with('_') { |
| 37 | + &result[1..] |
| 38 | + } else { |
| 39 | + &result |
| 40 | + }; |
| 41 | + |
| 42 | + result.parse().unwrap() |
| 43 | +} |
0 commit comments