bluejay_validator/executable/document/error/
directive_error.rs1use bluejay_core::definition::{DirectiveDefinition, DirectiveLocation, SchemaDefinition};
2use bluejay_core::executable::ExecutableDocument;
3use bluejay_core::AsIter;
4#[cfg(feature = "parser-integration")]
5use bluejay_parser::{
6 ast::executable::ExecutableDocument as ParserExecutableDocument,
7 error::{Annotation, Error as ParserError},
8 HasSpan,
9};
10use itertools::Itertools;
11
12pub enum DirectiveError<'a, const CONST: bool, E: ExecutableDocument, S: SchemaDefinition> {
13 DirectiveDoesNotExist {
14 directive: &'a E::Directive<CONST>,
15 },
16 DirectiveInInvalidLocation {
17 directive: &'a E::Directive<CONST>,
18 directive_definition: &'a S::DirectiveDefinition,
19 location: DirectiveLocation,
20 },
21 DirectivesNotUniquePerLocation {
22 directives: Vec<&'a E::Directive<CONST>>,
23 directive_definition: &'a S::DirectiveDefinition,
24 },
25}
26
27#[cfg(feature = "parser-integration")]
28impl<'a, const CONST: bool, S: SchemaDefinition>
29 From<DirectiveError<'a, CONST, ParserExecutableDocument<'a>, S>> for ParserError
30{
31 fn from(value: DirectiveError<'a, CONST, ParserExecutableDocument<'a>, S>) -> Self {
32 match value {
33 DirectiveError::DirectiveDoesNotExist { directive } => Self::new(
34 format!(
35 "No directive definition with name `@{}`",
36 directive.name().as_ref()
37 ),
38 Some(Annotation::new(
39 "No directive definition with this name",
40 directive.name().span().clone(),
41 )),
42 Vec::new(),
43 ),
44 DirectiveError::DirectiveInInvalidLocation {
45 directive,
46 directive_definition,
47 location,
48 } => Self::new(
49 format!(
50 "Directive @{} cannot be used at location {location}. It is only allowed at the following locations: {}",
51 directive.name().as_ref(),
52 directive_definition.locations().iter().join(", "),
53 ),
54 Some(Annotation::new(
55 format!("Cannot be used at location {location}"),
56 directive.span().clone(),
57 )),
58 Vec::new(),
59 ),
60 DirectiveError::DirectivesNotUniquePerLocation { directives, directive_definition } => Self::new(
61 format!(
62 "Directive @{} is not repeatable but was used multiple times in the same location",
63 directive_definition.name(),
64 ),
65 None,
66 directives.into_iter().map(|directive| Annotation::new(
67 "Usage of directive",
68 directive.span().clone(),
69 )).collect(),
70 ),
71 }
72 }
73}