use bluejay_core::definition::{DirectiveDefinition, DirectiveLocation, SchemaDefinition};
use bluejay_core::executable::ExecutableDocument;
use bluejay_core::AsIter;
#[cfg(feature = "parser-integration")]
use bluejay_parser::{
ast::executable::ExecutableDocument as ParserExecutableDocument,
error::{Annotation, Error as ParserError},
HasSpan,
};
use itertools::Itertools;
pub enum DirectiveError<'a, const CONST: bool, E: ExecutableDocument, S: SchemaDefinition> {
DirectiveDoesNotExist {
directive: &'a E::Directive<CONST>,
},
DirectiveInInvalidLocation {
directive: &'a E::Directive<CONST>,
directive_definition: &'a S::DirectiveDefinition,
location: DirectiveLocation,
},
DirectivesNotUniquePerLocation {
directives: Vec<&'a E::Directive<CONST>>,
directive_definition: &'a S::DirectiveDefinition,
},
}
#[cfg(feature = "parser-integration")]
impl<'a, const CONST: bool, S: SchemaDefinition>
From<DirectiveError<'a, CONST, ParserExecutableDocument<'a>, S>> for ParserError
{
fn from(value: DirectiveError<'a, CONST, ParserExecutableDocument<'a>, S>) -> Self {
match value {
DirectiveError::DirectiveDoesNotExist { directive } => Self::new(
format!(
"No directive definition with name `@{}`",
directive.name().as_ref()
),
Some(Annotation::new(
"No directive definition with this name",
directive.name().span().clone(),
)),
Vec::new(),
),
DirectiveError::DirectiveInInvalidLocation {
directive,
directive_definition,
location,
} => Self::new(
format!(
"Directive @{} cannot be used at location {location}. It is only allowed at the following locations: {}",
directive.name().as_ref(),
directive_definition.locations().iter().join(", "),
),
Some(Annotation::new(
format!("Cannot be used at location {location}"),
directive.span().clone(),
)),
Vec::new(),
),
DirectiveError::DirectivesNotUniquePerLocation { directives, directive_definition } => Self::new(
format!(
"Directive @{} is not repeatable but was used multiple times in the same location",
directive_definition.name(),
),
None,
directives.into_iter().map(|directive| Annotation::new(
"Usage of directive",
directive.span().clone(),
)).collect(),
),
}
}
}