zyn 0.5.4

A proc macro framework with templates, composable elements, and built-in diagnostics
Documentation
use zyn::ext::DataExt;
use zyn::syn;

#[test]
fn is_struct_for_struct() {
    let input: syn::DeriveInput = zyn::parse!("struct Foo;" => syn::DeriveInput).unwrap();
    assert!(input.data.is_struct());
    assert!(!input.data.is_enum());
    assert!(!input.data.is_union());
}

#[test]
fn is_enum_for_enum() {
    let input: syn::DeriveInput = zyn::parse!("enum Foo { A, B }" => syn::DeriveInput).unwrap();
    assert!(input.data.is_enum());
    assert!(!input.data.is_struct());
}

#[test]
fn as_struct_returns_data() {
    let input: syn::DeriveInput = zyn::parse!("struct Foo { x: i32 }" => syn::DeriveInput).unwrap();
    assert!(input.data.as_struct().is_some());
}

#[test]
fn as_enum_returns_data() {
    let input: syn::DeriveInput =
        zyn::parse!("enum Color { Red, Green, Blue }" => syn::DeriveInput).unwrap();
    let data = input.data.as_enum();
    assert!(data.is_some());
    assert_eq!(data.unwrap().variants.len(), 3);
}

#[test]
fn as_struct_none_for_enum() {
    let input: syn::DeriveInput = zyn::parse!("enum Foo { A }" => syn::DeriveInput).unwrap();
    assert!(input.data.as_struct().is_none());
}

#[zyn::element]
pub fn describe_data(data: syn::Data, name: syn::Ident) -> zyn::TokenStream {
    use zyn::ext::DataExt;

    if data.is_struct() {
        zyn::zyn!(
            impl {{ name }} {
                fn kind(&self) -> &str { "struct" }
            }
        )
    } else if data.is_enum() {
        zyn::zyn!(
            impl {{ name }} {
                fn kind(&self) -> &str { "enum" }
            }
        )
    } else {
        zyn::Output::default()
    }
}

#[test]
fn element_renders_struct_kind() {
    let input: zyn::Input = zyn::parse!("struct Foo;" => syn::DeriveInput)
        .unwrap()
        .into();
    let output = zyn::zyn!(
        @describe_data(
            data = input.as_derive().unwrap().data.clone(),
            name = input.ident().clone(),
        )
    );
    zyn::assert_tokens_contain!(output, "struct");
}

#[test]
fn element_renders_enum_kind() {
    let input: zyn::Input = zyn::parse!("enum Bar { A }" => syn::DeriveInput)
        .unwrap()
        .into();
    let output = zyn::zyn!(
        @describe_data(
            data = input.as_derive().unwrap().data.clone(),
            name = input.ident().clone(),
        )
    );
    zyn::assert_tokens_contain!(output, "enum");
}