cynic_codegen/
schema_module_attr.rs

1//! The implementation of the schema attribute for modules.
2
3use std::path::PathBuf;
4
5use proc_macro2::TokenStream;
6use quote::quote;
7use syn::{self, parse_quote, Item, LitStr};
8
9use crate::schema::parser::SchemaLoadError;
10
11pub fn attribute_impl(
12    schema_literal: LitStr,
13    module: &mut syn::ItemMod,
14) -> Result<TokenStream, syn::Error> {
15    let schema_name = schema_literal.value();
16
17    let filename_str = LitStr::new(
18        &format!("/cynic-schemas/{schema_name}.rs"),
19        schema_literal.span(),
20    );
21
22    let Ok(out_dir) = std::env::var("OUT_DIR") else {
23        return Err(SchemaLoadError::UnknownOutDirWithNamedSchema(schema_name)
24            .into_syn_error(schema_literal.span()));
25    };
26
27    let mut path = PathBuf::from(&out_dir);
28    path.push("cynic-schemas");
29    path.push(format!("{schema_name}.rs"));
30    if !path.exists() {
31        return Err(
32            SchemaLoadError::NamedSchemaNotFound(schema_name).into_syn_error(schema_literal.span())
33        );
34    }
35
36    // Silence a bunch of warnings inside this module
37    module.attrs.push(parse_quote! {
38        #[allow(clippy::all, clippy::pedantic, clippy::nursery, non_snake_case, non_camel_case_types, dead_code)]
39    });
40
41    let include: Item = parse_quote! {
42        include!(concat!(env!("OUT_DIR"), #filename_str));
43    };
44    if let Some((_, items)) = &mut module.content {
45        items.push(include);
46    }
47
48    Ok(quote! { #module })
49}