cynic-codegen 3.13.2

Procedural macro code generation for cynic - a code first GraphQL client for Rust
Documentation
mod output;
mod parsing;

use proc_macro2::Span;
use syn::Ident;

use crate::{
    error::Errors,
    schema::{Schema, Unvalidated, types::Directive},
};

pub use self::{
    output::Output,
    parsing::{FieldDirective, directives_from_field_attrs},
};

use super::arguments::{ArgumentLiteral, FieldArgument, analyse::AnalysedDirectiveArguments};

pub struct AnalysedFieldDirective<'a> {
    directive: Directive<'a>,
    arguments: AnalysedDirectiveArguments<'a>,
}

pub fn process_directive<'a>(
    schema: &'a Schema<'a, Unvalidated>,
    directive: parsing::FieldDirective,
    variables_fields: Option<&syn::Path>,
    span: Span,
) -> Result<AnalysedFieldDirective<'a>, Errors> {
    match directive {
        FieldDirective::Skip(inner) => {
            let Some(directive) = schema.lookup_directive("skip")? else {
                return Err(syn::Error::new(span, "Unknown directive: skip").into());
            };

            let arguments = vec![FieldArgument {
                argument_name: Ident::new("if", span),
                value: super::arguments::FieldArgumentValue::Literal(match inner {
                    parsing::BooleanLiteral::Boolean(value) => {
                        ArgumentLiteral::Literal(syn::Lit::Bool(syn::LitBool { value, span }))
                    }
                    parsing::BooleanLiteral::Variable(var, span) => {
                        ArgumentLiteral::Variable(var, span)
                    }
                }),
                requires_feature: None,
            }];

            let arguments = super::arguments::analyse::analyse_directive_arguments(
                schema,
                arguments,
                &directive,
                variables_fields,
                span,
            )?;

            Ok(AnalysedFieldDirective {
                directive,
                arguments,
            })
        }
        FieldDirective::Include(inner) => {
            let Some(directive) = schema.lookup_directive("include")? else {
                return Err(syn::Error::new(span, "Unknown directive: include").into());
            };
            let arguments = vec![FieldArgument {
                argument_name: Ident::new("if", span),
                value: super::arguments::FieldArgumentValue::Literal(match inner {
                    parsing::BooleanLiteral::Boolean(value) => {
                        ArgumentLiteral::Literal(syn::Lit::Bool(syn::LitBool { value, span }))
                    }
                    parsing::BooleanLiteral::Variable(var, span) => {
                        ArgumentLiteral::Variable(var, span)
                    }
                }),
                requires_feature: None,
            }];

            let arguments = super::arguments::analyse::analyse_directive_arguments(
                schema,
                arguments,
                &directive,
                variables_fields,
                span,
            )?;

            Ok(AnalysedFieldDirective {
                directive,
                arguments,
            })
        }
        FieldDirective::Other { name, arguments } => {
            let Some(directive) = schema.lookup_directive(&name.to_string())? else {
                return Err(syn::Error::new(span, format!("Unknown directive: {name}")).into());
            };
            let arguments = super::arguments::analyse::analyse_directive_arguments(
                schema,
                arguments,
                &directive,
                variables_fields,
                span,
            )?;

            Ok(AnalysedFieldDirective {
                directive,
                arguments,
            })
        }
    }
}