blob: 8cb88d366ac4d9774f80352832e0baff5711cd3f (
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
|
//! 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()?,
})
}
}
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();
// If the input string is empty, return an empty Node
if path_str.is_empty() {
return quote! {
mingling::Node::default()
}
.into();
}
// 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()
}
|