reifydb_macro_impl/
generate.rs1use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
5
6pub fn ident(name: &str) -> TokenTree {
7 TokenTree::Ident(Ident::new(name, Span::call_site()))
8}
9
10pub fn underscore() -> TokenTree {
11 "_".parse::<TokenStream>().unwrap().into_iter().next().unwrap()
12}
13
14#[allow(dead_code)]
15pub fn ident_raw(name: &str) -> TokenTree {
16 if let Some(stripped) = name.strip_prefix("r#") {
17 TokenTree::Ident(Ident::new_raw(stripped, Span::call_site()))
18 } else {
19 TokenTree::Ident(Ident::new(name, Span::call_site()))
20 }
21}
22
23pub fn punct(ch: char) -> TokenTree {
24 TokenTree::Punct(Punct::new(ch, Spacing::Alone))
25}
26
27pub fn punct_joint(ch: char) -> TokenTree {
28 TokenTree::Punct(Punct::new(ch, Spacing::Joint))
29}
30
31pub fn literal_str(s: &str) -> TokenTree {
32 TokenTree::Literal(Literal::string(s))
33}
34
35pub fn literal_usize(n: usize) -> TokenTree {
36 TokenTree::Literal(Literal::usize_unsuffixed(n))
37}
38
39pub fn group(delimiter: Delimiter, tokens: impl IntoIterator<Item = TokenTree>) -> TokenTree {
40 TokenTree::Group(Group::new(delimiter, tokens.into_iter().collect()))
41}
42
43pub fn parens(tokens: impl IntoIterator<Item = TokenTree>) -> TokenTree {
44 group(Delimiter::Parenthesis, tokens)
45}
46
47pub fn braces(tokens: impl IntoIterator<Item = TokenTree>) -> TokenTree {
48 group(Delimiter::Brace, tokens)
49}
50
51pub fn brackets(tokens: impl IntoIterator<Item = TokenTree>) -> TokenTree {
52 group(Delimiter::Bracket, tokens)
53}
54
55pub fn path_sep() -> impl Iterator<Item = TokenTree> {
56 [punct_joint(':'), punct(':')].into_iter()
57}
58
59pub fn path(segments: &[&str]) -> Vec<TokenTree> {
60 let mut expanded: Vec<&str> = Vec::new();
61 for seg in segments {
62 if seg.is_empty() {
63 expanded.push("");
64 } else {
65 for part in seg.split("::") {
66 expanded.push(part);
67 }
68 }
69 }
70
71 let mut tokens = Vec::new();
72 let mut prev_was_empty = false;
73
74 for (i, seg) in expanded.iter().enumerate() {
75 let need_sep = if i == 0 {
76 seg.is_empty()
77 } else {
78 !prev_was_empty
79 };
80
81 if need_sep {
82 tokens.extend(path_sep());
83 }
84
85 if !seg.is_empty() {
86 tokens.push(ident(seg));
87 }
88
89 prev_was_empty = seg.is_empty();
90 }
91 tokens
92}
93
94pub fn arrow() -> impl Iterator<Item = TokenTree> {
95 [punct_joint('-'), punct('>')].into_iter()
96}
97
98pub fn fat_arrow() -> impl Iterator<Item = TokenTree> {
99 [punct_joint('='), punct('>')].into_iter()
100}
101
102#[allow(dead_code)]
103pub fn generics(inner: impl IntoIterator<Item = TokenTree>) -> Vec<TokenTree> {
104 let mut tokens = vec![punct('<')];
105 tokens.extend(inner);
106 tokens.push(punct('>'));
107 tokens
108}
109
110#[allow(dead_code)]
111pub fn extend(tokens: &mut Vec<TokenTree>, iter: impl IntoIterator<Item = TokenTree>) {
112 tokens.extend(iter);
113}
114
115pub fn compile_error(message: &str) -> TokenStream {
116 let tokens = vec![ident("compile_error"), punct('!'), parens([literal_str(message)])];
117 tokens.into_iter().collect()
118}