From 3378d141ec47cefca17ecaf0aa83e377b3990d7f Mon Sep 17 00:00:00 2001 From: Colin Kiegel Date: Sun, 5 Mar 2017 14:16:52 +0100 Subject: [PATCH 1/3] computation in implementation implement #10 --- src/lib.rs | 9 +++++-- tests/test.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4bc4188..892cb05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,8 +98,8 @@ macro_rules! pounded_var_names { pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) }; - ($finish:ident ($($found:ident)*) # { $($inner:tt)* } $($rest:tt)*) => { - pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) + ($finish:ident ($($found:ident)*) # { $($ignore:tt)* } $($rest:tt)*) => { + pounded_var_names!($finish ($($found)*) $($rest)*) }; ($finish:ident ($($found:ident)*) # $first:ident $($rest:tt)*) => { @@ -219,6 +219,11 @@ macro_rules! quote_each_token { quote_each_token!($tokens $($rest)*); }; + ($tokens:ident # { $($inner:tt)* } $($rest:tt)*) => { + $crate::ToTokens::to_tokens(&{ $($inner)* }, &mut $tokens); + quote_each_token!($tokens $($rest)*); + }; + ($tokens:ident # $first:ident $($rest:tt)*) => { $crate::ToTokens::to_tokens(&$first, &mut $tokens); quote_each_token!($tokens $($rest)*); diff --git a/tests/test.rs b/tests/test.rs index 17dc990..1de9e5d 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -33,6 +33,73 @@ fn test_quote_impl() { assert_eq!(expected, tokens.as_str()); } +#[test] +fn test_simple_computation_in_interpolation() { + let foo: [u32; 3] = [0, 1, 42]; + let tokens = quote!(#{foo[2]}); + + let expected = "42u32"; + + assert_eq!(expected, tokens.as_str()); +} + +#[test] +fn test_complex_computation_in_interpolation() { + let tokens = quote!( + let #{ + struct Foo { } + + impl quote::ToTokens for Foo { + fn to_tokens(&self, tokens: &mut quote::Tokens) { + tokens.append("foo") + } + } + + Foo { } + } = #{ quote!("Hello World!") }; + ); + + let expected = "let foo = \"Hello World!\" ;"; + + assert_eq!(expected, tokens.as_str()); +} + +#[test] +fn test_simple_computation_in_loop() { + let foo: [&'static str; 3] = ["1", "2", "3"]; + let iter = foo.iter(); + let tokens = quote!(#( #iter, #{"+"}, )*); + + let expected = r#""1" , "+" , "2" , "+" , "3" , "+" ,"#; + + assert_eq!(expected, tokens.as_str()); +} + +#[test] +fn test_complex_computation_in_loop() { + let foo: [&'static str; 3] = ["1", "2", "3"]; + let iter = foo.iter(); + let tokens = quote!( + #( // loop + #{ // interpolation + "this will be ignored because the outer loop is empty" + } + )* + #( // loop + #iter, + #{ // interpolation + let foo = ["e", "+", "a"]; + let iter = foo.iter(); + quote!( #(#iter),*, ) + } + )* + ); + + let expected = r#""1" , "e" , "+" , "a" , "2" , "e" , "+" , "a" , "3" , "e" , "+" , "a" ,"#; + + assert_eq!(expected, tokens.as_str()); +} + #[test] fn test_substitution() { let x = X; From d786a28236ca109acc6950b119d5b75ff21aec24 Mon Sep 17 00:00:00 2001 From: Colin Kiegel Date: Sun, 5 Mar 2017 20:19:58 +0100 Subject: [PATCH 2/3] add documentation for computation in interpolation --- src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 892cb05..81883e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,19 @@ //! return quote! { /* ... */ #t /* ... */ }; //! ``` //! +//! You can use `#{...}` for arbitrary computations inside of quotations - _the result_ will then +//! be spliced into the token stream: +//! +//! - `#{a[0]}` - index arrays +//! - `#{x.foo}` - access fields +//! - `#{format!("{:?}", ::std::time::Instant::now())}` - arbitrary computations and nested macros, +//! which are valid Rust +//! +//! Note: +//! - interpolation inside of `#foo` inside of `#{...}` is disabled by design. `#{#foo}` is +//! illegal, but on the other hand you can `#{quote!(#foo)}` (if you _really want to_). +//! - computations `#{...}` _inside_ of repetitions `#(...)*` are evaluated each time. +//! //! Call `to_string()` or `as_str()` on a Tokens to get a `String` or `&str` of Rust //! code. //! From 49ce2c4614ce3b1da77e45b0b838628f20348cd4 Mon Sep 17 00:00:00 2001 From: Colin Kiegel Date: Mon, 6 Mar 2017 10:31:41 +0100 Subject: [PATCH 3/3] fix test --- tests/test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test.rs b/tests/test.rs index 1d3da0d..fecb14b 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -96,6 +96,8 @@ fn test_complex_computation_in_loop() { ); let expected = r#""1" , "e" , "+" , "a" , "2" , "e" , "+" , "a" , "3" , "e" , "+" , "a" ,"#; + + assert_eq!(expected, tokens.as_str()); } #[test]