cynic_codegen/schema_for_derives/
utils.rs1use darling::ast::NestedMeta;
2use syn::{Attribute, Item, Meta};
3
4#[derive(Debug, PartialEq, Eq)]
5pub enum Derive {
6 QueryFragment,
7 QueryVariables,
8 InlineFragments,
9 Enum,
10 Scalar,
11 InputObject,
12}
13
14pub fn find_derives(item: &Item) -> Vec<Derive> {
15 match item {
16 Item::Struct(s) => derive_from_attributes(&s.attrs),
17 Item::Enum(e) => derive_from_attributes(&e.attrs),
18 _ => vec![],
19 }
20}
21
22fn derive_from_attributes(attrs: &[Attribute]) -> Vec<Derive> {
23 let attr = attrs.iter().find(|attr| attr.path().is_ident("derive"));
24
25 if attr.is_none() {
26 return vec![];
27 }
28 let attr = attr.unwrap();
29
30 let meta_list = match &attr.meta {
31 Meta::List(list) => list,
32 _ => {
33 return vec![];
34 }
35 };
36
37 NestedMeta::parse_meta_list(meta_list.tokens.clone())
38 .unwrap_or_default()
39 .iter()
40 .filter_map(derive_for_nested_meta)
41 .collect()
42}
43
44fn derive_for_nested_meta(nested: &NestedMeta) -> Option<Derive> {
45 if let NestedMeta::Meta(Meta::Path(path)) = nested {
46 if let Some(last) = path.segments.last() {
47 match last.ident.to_string().as_ref() {
48 "QueryFragment" => return Some(Derive::QueryFragment),
49 "QueryVariables" => return Some(Derive::QueryVariables),
50 "InlineFragments" => return Some(Derive::InlineFragments),
51 "Enum" => return Some(Derive::Enum),
52 "Scalar" => return Some(Derive::Scalar),
53 "InputObject" => return Some(Derive::InputObject),
54 _ => (),
55 }
56 }
57 }
58
59 None
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use quote::quote;
66
67 #[test]
68 fn test_find_derives_with_fragment() {
69 let item: syn::Item = syn::parse2(quote! {
70 #[derive(Debug, cynic::QueryFragment)]
71 struct Something {}
72 })
73 .unwrap();
74
75 assert_eq!(find_derives(&item), vec![Derive::QueryFragment]);
76 }
77
78 #[test]
79 fn test_find_derives_when_no_cynic_derive() {
80 let item: syn::Item = syn::parse2(quote! {
81 #[derive(Debug)]
82 struct Something {}
83 })
84 .unwrap();
85
86 assert_eq!(find_derives(&item), vec![]);
87 }
88
89 #[test]
90 fn test_find_derives_when_no_derive() {
91 let item: syn::Item = syn::parse2(quote! {
92 struct Something {}
93 })
94 .unwrap();
95
96 assert_eq!(find_derives(&item), vec![]);
97 }
98
99 #[test]
100 fn test_find_derives_on_enum() {
101 let item: syn::Item = syn::parse2(quote! {
102 #[derive(cynic::InlineFragments)]
103 enum Something {}
104 })
105 .unwrap();
106
107 assert_eq!(find_derives(&item), vec![Derive::InlineFragments]);
108 }
109}