cynic-codegen 3.13.2

Procedural macro code generation for cynic - a code first GraphQL client for Rust
Documentation
use darling::ast::NestedMeta;
use syn::{Attribute, Item, Meta};

#[derive(Debug, PartialEq, Eq)]
pub enum Derive {
    QueryFragment,
    QueryVariables,
    InlineFragments,
    Enum,
    Scalar,
    InputObject,
}

pub fn find_derives(item: &Item) -> Vec<Derive> {
    match item {
        Item::Struct(s) => derive_from_attributes(&s.attrs),
        Item::Enum(e) => derive_from_attributes(&e.attrs),
        _ => vec![],
    }
}

fn derive_from_attributes(attrs: &[Attribute]) -> Vec<Derive> {
    let attr = attrs.iter().find(|attr| attr.path().is_ident("derive"));

    if attr.is_none() {
        return vec![];
    }
    let attr = attr.unwrap();

    let meta_list = match &attr.meta {
        Meta::List(list) => list,
        _ => {
            return vec![];
        }
    };

    NestedMeta::parse_meta_list(meta_list.tokens.clone())
        .unwrap_or_default()
        .iter()
        .filter_map(derive_for_nested_meta)
        .collect()
}

fn derive_for_nested_meta(nested: &NestedMeta) -> Option<Derive> {
    if let NestedMeta::Meta(Meta::Path(path)) = nested {
        if let Some(last) = path.segments.last() {
            match last.ident.to_string().as_ref() {
                "QueryFragment" => return Some(Derive::QueryFragment),
                "QueryVariables" => return Some(Derive::QueryVariables),
                "InlineFragments" => return Some(Derive::InlineFragments),
                "Enum" => return Some(Derive::Enum),
                "Scalar" => return Some(Derive::Scalar),
                "InputObject" => return Some(Derive::InputObject),
                _ => (),
            }
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use super::*;
    use quote::quote;

    #[test]
    fn test_find_derives_with_fragment() {
        let item: syn::Item = syn::parse2(quote! {
            #[derive(Debug, cynic::QueryFragment)]
            struct Something {}
        })
        .unwrap();

        assert_eq!(find_derives(&item), vec![Derive::QueryFragment]);
    }

    #[test]
    fn test_find_derives_when_no_cynic_derive() {
        let item: syn::Item = syn::parse2(quote! {
            #[derive(Debug)]
            struct Something {}
        })
        .unwrap();

        assert_eq!(find_derives(&item), vec![]);
    }

    #[test]
    fn test_find_derives_when_no_derive() {
        let item: syn::Item = syn::parse2(quote! {
            struct Something {}
        })
        .unwrap();

        assert_eq!(find_derives(&item), vec![]);
    }

    #[test]
    fn test_find_derives_on_enum() {
        let item: syn::Item = syn::parse2(quote! {
            #[derive(cynic::InlineFragments)]
            enum Something {}
        })
        .unwrap();

        assert_eq!(find_derives(&item), vec![Derive::InlineFragments]);
    }
}