It is not possible. Macros cannot inspect and/or change the value of variables.
It is possible if the literal is embedded in the call (replace_macro!("Hello, world!", "world", "Rust");
) but requires a proc-macro: macro_rules!
macros cannot inspect and/or change literals.
It's a rather simple with a proc macro:
use quote::ToTokens;
use syn::parse::Parser;
use syn::spanned::Spanned;
type Args = syn::punctuated::Punctuated<syn::LitStr, syn::Token![,]>;
#[proc_macro]
pub fn replace_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input_span = input.span();
let args = match Args::parse_terminated.parse(input) {
Ok(args) => Vec::from_iter(args),
Err(err) => return err.into_compile_error().into(),
};
let (original, text, replacement) = match args.as_slice() {
[original, text, replacement] => (original.value(), text.value(), replacement.value()),
_ => {
return syn::Error::new(
input_span,
r#"expected `"<original>", "<text>", "<replacement>"`"#,
)
.into_compile_error()
.into()
}
};
original
.replace(&text, &replacement)
.into_token_stream()
.into()
}
It parses a list of three string literals, punctated by commas, then calls str::replace()
to do the real work.