blob: 3d9473f1f7bb2e7e688ea531e9c028cb5bb19828 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
//! Command Node Macro Implementation
//!
//! This module provides the `node` procedural macro for creating
//! command nodes from dot-separated path strings.
use just_fmt::kebab_case;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::{LitStr, Result as SynResult};
/// Parses a string literal input for the node macro
struct NodeInput {
path: LitStr,
}
impl Parse for NodeInput {
fn parse(input: ParseStream) -> SynResult<Self> {
Ok(NodeInput {
path: input.parse()?,
})
}
}
/// Implementation of the `node` procedural macro
///
/// # Examples
///
/// ```ignore
/// use mingling_macros::node;
///
/// // Creates: Node::default().join("root").join("subcommand").join("action")
/// let node = node!("root.subcommand.action");
/// ```
pub fn node(input: TokenStream) -> TokenStream {
// Parse the input as a string literal
let input_parsed = syn::parse_macro_input!(input as NodeInput);
let path_str = input_parsed.path.value();
// Split the path by dots
let parts: Vec<String> = path_str
.split('.')
.map(|s| kebab_case!(s).to_string())
.collect();
// Build the expression starting from Node::default()
let mut expr: TokenStream2 = quote! {
mingling::Node::default()
};
// Add .join() calls for each part of the path
for part in parts {
expr = quote! {
#expr.join(#part)
};
}
expr.into()
}
|