![github] ![crates-io] ![docs-rs] ![workflow]
This crate is meant to be a complement to [quote]. Where as [quote] does quasi-quote interpolations at compile-time, this crate does them at run-time. This is handy for macros receiving templates from client code with markers to be replaced when the macro is run.
```rust use procmacro2::TokenStream; use tokenstream2-tmpl::interpolate; use quote::ToTokens; use std::collections::HashMap; use syn::{Ident, parsestr};
let input: TokenStream = parsestr("let NAME: int = 5;")?; let expected: TokenStream = parsestr("let age: int = 5;")?;
let mut replacements: HashMap<&str, &dyn ToTokens> = HashMap::new();
let ident = parse_str::
let output = interpolate(input, &replacements); assert_eq!( format!("{}", output), format!("{}", expected) );
```
Here input
might be some input to a macro that functions as a template. [quote] would have tried to expand NAME
at the macro's compile-time. [tokenstream2-tmpl] will expand it at the macro's run-time.
```rust extern crate procmacro; use procmacro2::TokenStream; use std::collections::HashMap; use syn::{Ident, parse::{Parse, ParseStream, Result}, parsemacroinput, punctuated::Punctuated, Token}; use tokenstream2-tmpl::{Interpolate, interpolate}; use quote::ToTokens;
/// Create a token for macro using syn
/// Type that holds a key and the value it maps to.
/// An acceptable stream will have the following form:
/// text
/// key => value
///
struct KeyValue {
pub key: Ident,
pub arrow_token: Token![=>],
pub value: Ident,
}
/// Make KeyValue parsable from a token stream
impl Parse for KeyValue {
fn parse(input: ParseStream) -> Result
/// Make KeyValue interpolatible impl Interpolate for KeyValue { fn interpolate(&self, stream: TokenStream) -> TokenStream { let mut replacements: HashMap<_, &dyn ToTokens> = HashMap::new();
// Replace each "KEY" with the key
replacements.insert("KEY", &self.key);
// Replace each "VALUE" with the value
replacements.insert("VALUE", &self.value);
interpolate(stream, &replacements)
}
}
/// Macro to take a list of key-values with a template to expand each key-value
pub fn map(tokens: procmacro::TokenStream, template: procmacro::TokenStream) -> procmacro::TokenStream {
// Parse a comma separated list of key-values
let maps =
parsemacroinput!(tokens with Punctuated::
maps.interpolate(template.into()).into()
}
pub fn main() { #[map( usize => 10, isize => -2, bool => false, )] let _: KEY = VALUE; // Output: // let _: usize = 10; // let _: isize = -2; // let _: bool = false; } ```
License: MIT