summaryrefslogtreecommitdiff
path: root/rola-vcs/internal_macros/src/constants.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rola-vcs/internal_macros/src/constants.rs')
-rw-r--r--rola-vcs/internal_macros/src/constants.rs115
1 files changed, 0 insertions, 115 deletions
diff --git a/rola-vcs/internal_macros/src/constants.rs b/rola-vcs/internal_macros/src/constants.rs
deleted file mode 100644
index 2e76bfe..0000000
--- a/rola-vcs/internal_macros/src/constants.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use proc_macro::TokenStream;
-use quote::{format_ident, quote};
-use syn::{Expr, Item, ItemConst, ItemMod, Lit, parse_macro_input, parse_quote};
-
-/// Entry point called from lib.rs.
-pub fn expand(_attr: TokenStream, item: TokenStream) -> TokenStream {
- let mut input_mod = parse_macro_input!(item as ItemMod);
-
- let (_, items) = match &mut input_mod.content {
- Some(content) => content,
- None => panic!("#[constants] can only be applied to a module with a body"),
- };
-
- let mut new_items: Vec<Item> = Vec::with_capacity(items.len());
-
- for item in items.iter() {
- if let Item::Const(const_item) = item {
- let func = transform_const(const_item);
- new_items.push(func);
- } else {
- new_items.push(item.clone());
- }
- }
-
- let mod_ident = &input_mod.ident;
- let vis = &input_mod.vis;
-
- let output = quote! {
- #[allow(non_snake_case)]
- #vis mod #mod_ident {
- #(#new_items)*
- }
- };
-
- output.into()
-}
-
-/// Transforms a single `const` item into a function.
-fn transform_const(const_item: &ItemConst) -> Item {
- let name = &const_item.ident;
- let attrs = &const_item.attrs;
-
- // Extract the string literal value from the const
- let value_str = match &*const_item.expr {
- Expr::Lit(expr_lit) => match &expr_lit.lit {
- Lit::Str(lit_str) => lit_str.value(),
- _ => panic!(
- "#[constants] only supports `&str` literals, \
- but `{name}` has a non-string literal"
- ),
- },
- _ => panic!(
- "#[constants] only supports literal expressions, \
- but `{name}` has a non-literal expression"
- ),
- };
-
- let placeholders = extract_placeholders(&value_str);
-
- if placeholders.is_empty() {
- parse_quote! {
- #(#attrs)*
- pub fn #name() -> String {
- #value_str.to_string()
- }
- }
- } else {
- let params: Vec<_> = placeholders
- .iter()
- .map(|p| {
- let ident = format_ident!("{p}");
- quote! { #ident: impl ::core::convert::AsRef<str> }
- })
- .collect();
-
- let format_args: Vec<_> = placeholders
- .iter()
- .map(|p| {
- let ident = format_ident!("{p}");
- quote! { #ident = #ident.as_ref() }
- })
- .collect();
-
- parse_quote! {
- #(#attrs)*
- pub fn #name(#(#params),*) -> String {
- ::std::format!(#value_str, #(#format_args),*)
- }
- }
- }
-}
-
-/// Extracts all `{name}` placeholder identifiers from a format string.
-fn extract_placeholders(s: &str) -> Vec<String> {
- let mut placeholders = Vec::new();
- let mut chars = s.char_indices().peekable();
-
- while let Some((_, c)) = chars.next() {
- if c == '{' {
- let mut name = String::new();
- for (_, c) in &mut chars {
- if c == '}' {
- break;
- }
- name.push(c);
- }
- let trimmed = name.trim().to_string();
- if !trimmed.is_empty() {
- placeholders.push(trimmed);
- }
- }
- }
-
- placeholders
-}