code-product-lib 0.4.1

macro producing multiple expansions
Documentation
use quote::quote;

use code_product_lib::*;

#[cfg(test)]
macro_rules! assert_expansion {
    ($expand_mode:ident {$($in:tt)*} == {$($out:tt)*}) => {
        let input = quote! { $($in)* };
        let output = expand_products(input, ScopeMode::$expand_mode);
        let expected = quote! { $($out)* };
        assert_eq!(output.to_string(), expected.to_string());
    };
    ($($in:tt)*) => {
        assert_expansion!(Expand {$($in)*} == {$($in)*});
    };
    (SubExpand $($in:tt)*) => {
        assert_expansion!(SubExpand {$($in)*} == {$($in)*});
    };
}

#[test]
fn smoke() {
    assert_expansion! {
        #[newtype]
        pub struct MyNewtype<T>(T);
    };
}

#[test]
fn expansion() {
    assert_expansion! {
        Expand {
            $((a)(b)) $((c)(d)) $((e)(f)) ;
        } == {
            a c e ;
            b c e ;
            a d e ;
            b d e ;
            a c f ;
            b c f ;
            a d f ;
            b d f ;
        }
    };
}

#[test]
fn nested_expansion() {
    assert_expansion! {
        Expand {
            $((a)(b)) ${ $((c)(d)) $((e)(f)) } ;
        } == {
            a c e d e c f d f ;
            b c e d e c f d f ;
        }
    };
}

#[test]
fn index_expansion() {
    assert_expansion! {
        Expand {
            $((a)(b)) $0 ;
        } == {
            a a ;
            b b ;
        }
    };
}

#[test]
fn name_expansion() {
    assert_expansion! {
        Expand {
            $(foo: (a)(b)) $foo ;
        } == {
            a ;
            b ;
        }
    };
}

#[test]
fn visible_name_expansion() {
    assert_expansion! {
        Expand {
            $($foo: (a)(b)) $foo ;
        } == {
            a a ;
            b b ;
        }
    };
}

#[test]
fn single_definition() {
    assert_expansion! {
        Expand {
            $($foo: a b ) $foo ;
            $foo ;
            $(bar: c d) $bar ;
            $bar ;
        } == {
            a b a b ;
            a b ;
            c d ;
            c d ;
        }
    };
}

#[test]
fn syntax_example_named() {
    assert_expansion! {
        Expand {
            $(Type: (This) (That))
            impl Trait<$($T: (Foo)(Bar))> for $Type<$T> {}
        } == {
            impl Trait<Foo> for This<Foo> {}
            impl Trait<Foo> for That<Foo> {}
            impl Trait<Bar> for This<Bar> {}
            impl Trait<Bar> for That<Bar> {}
        }
    };
}

#[test]
fn syntax_example_indexed() {
    assert_expansion! {
        Expand {
            impl Trait<$((Foo)(Bar))> for $((This)(That))<$0> {}
        } == {
            impl Trait<Foo> for This<Foo> {}
            impl Trait<Bar> for This<Bar> {}
            impl Trait<Foo> for That<Foo> {}
            impl Trait<Bar> for That<Bar> {}
        }
    };
}

#[test]
fn empty_linear_scope() {
    assert_expansion! {
        Expand {
            $[]
        } == {
        }
    };
}

#[test]
fn linear_scope() {
    assert_expansion! {
        Expand {
            $[
                $(name: (one)(two)(three))
                $(number: (1)(2)(3))
                $(xnumber: (1)(2)(3))
                $name:$number ;
            ]
        } == {
            one:1 ;
            two:2 ;
            three:3 ;
        }
    };
}

#[test]
fn linear_scope_no_defs() {
    assert_expansion! {
        Expand {
            $[
                foobar ;
            ]
        } == {
            foobar ;
        }
    };
}

#[test]
#[should_panic]
fn linear_scope_len_error() {
    assert_expansion! {
        Expand {
            $[
                $(name: (one))
                $(number: (1)(2))
            ]
        } == {
        }
    };
}

#[test]
fn auto_brace_semi() {
    assert_expansion! {
        AutoBraceSemi {
            $((First)(Second)) { }
            $((Third)(Fourth)) ;
        } == {
            First { }
            Second { }
            Third ;
            Fourth ;
        }
    };
}