add recursion to replace! macro.
This commit is contained in:
parent
3f24c626f7
commit
b0bfd103f7
3 changed files with 28 additions and 15 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ident_concat"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/tudbut/ident-concat"
|
||||
description = "Concatenates identifiers."
|
||||
|
|
|
|||
33
src/lib.rs
33
src/lib.rs
|
|
@ -3,7 +3,6 @@ extern crate proc_macro;
|
|||
use proc_macro::{token_stream::IntoIter, *};
|
||||
|
||||
fn concat(ts: &mut IntoIter, end: Option<char>) -> Ident {
|
||||
|
||||
let mut ident = String::new();
|
||||
for x in ts {
|
||||
if let TokenTree::Ident(x) = x {
|
||||
|
|
@ -26,9 +25,27 @@ pub fn ident(ts: TokenStream) -> TokenStream {
|
|||
TokenStream::from(TokenTree::Ident(concat(&mut ts.into_iter(), None)))
|
||||
}
|
||||
|
||||
fn convert_replace(tt: TokenTree, to_replace: &TokenTree, ident: &Ident) -> TokenTree {
|
||||
match (&tt, to_replace) {
|
||||
(TokenTree::Ident(x), TokenTree::Ident(to_replace))
|
||||
if x.to_string() == to_replace.to_string() =>
|
||||
{
|
||||
TokenTree::Ident(ident.clone())
|
||||
}
|
||||
(TokenTree::Group(x), _) => TokenTree::Group(Group::new(
|
||||
x.delimiter(),
|
||||
TokenStream::from_iter(
|
||||
x.stream()
|
||||
.into_iter()
|
||||
.map(|x| convert_replace(x, to_replace, ident)),
|
||||
),
|
||||
)),
|
||||
_ => tt,
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
/// Replaces identifiers with concatenated ones. This will not recurse!
|
||||
/// Use multiple invocations for recursion.
|
||||
/// Replaces identifiers with concatenated ones.
|
||||
/// ```
|
||||
/// use ident_concat::replace;
|
||||
/// replace!{ placeholder te st:
|
||||
|
|
@ -42,13 +59,5 @@ pub fn replace(ts: TokenStream) -> TokenStream {
|
|||
.next()
|
||||
.expect("syntax: replace!(to_replace with _this: to_replace) => with_this");
|
||||
let ident = concat(&mut iter, Some(':'));
|
||||
TokenStream::from_iter(iter.map(|x| {
|
||||
if matches!((&x, &to_replace), (TokenTree::Ident(x), TokenTree::Ident(to_replace))
|
||||
if x.to_string() == to_replace.to_string())
|
||||
{
|
||||
TokenTree::Ident(ident.clone())
|
||||
} else {
|
||||
x
|
||||
}
|
||||
}))
|
||||
TokenStream::from_iter(iter.map(|x| convert_replace(x, &to_replace, &ident)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
use ident_concat::*;
|
||||
fn main() {
|
||||
let ident!(a b) = 4;
|
||||
let ident!(a b): u32 = 4;
|
||||
assert_eq!(ab, ident!(a b));
|
||||
replace! { placeholder te st:
|
||||
fn placeholder() -> u32 { 4 }
|
||||
assert_eq!(test(), 4);
|
||||
}
|
||||
replace! { placeholder a b c:
|
||||
fn placeholder(abc: u32) -> u32 { placeholder }
|
||||
assert_eq!(ab, abc(ab));
|
||||
}
|
||||
assert_eq!(test(), 4);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue