async_graphql/model/
directive.rs

1use std::collections::HashSet;
2
3use crate::{Enum, Object, model::__InputValue, registry};
4
5/// A Directive can be adjacent to many parts of the GraphQL language, a
6/// __DirectiveLocation describes one such possible adjacencies.
7#[derive(Debug, Enum, Copy, Clone, Eq, PartialEq)]
8#[graphql(internal, name = "__DirectiveLocation")]
9#[allow(non_camel_case_types)]
10pub enum __DirectiveLocation {
11    /// Location adjacent to a query operation.
12    QUERY,
13
14    /// Location adjacent to a mutation operation.
15    MUTATION,
16
17    /// Location adjacent to a subscription operation.
18    SUBSCRIPTION,
19
20    /// Location adjacent to a field.
21    FIELD,
22
23    /// Location adjacent to a fragment definition.
24    FRAGMENT_DEFINITION,
25
26    /// Location adjacent to a fragment spread.
27    FRAGMENT_SPREAD,
28
29    /// Location adjacent to an inline fragment.
30    INLINE_FRAGMENT,
31
32    /// Location adjacent to a variable definition.
33    VARIABLE_DEFINITION,
34
35    /// Location adjacent to a schema definition.
36    SCHEMA,
37
38    /// Location adjacent to a scalar definition.
39    SCALAR,
40
41    /// Location adjacent to an object type definition.
42    OBJECT,
43
44    /// Location adjacent to a field definition.
45    FIELD_DEFINITION,
46
47    /// Location adjacent to an argument definition.
48    ARGUMENT_DEFINITION,
49
50    /// Location adjacent to an interface definition.
51    INTERFACE,
52
53    /// Location adjacent to a union definition.
54    UNION,
55
56    /// Location adjacent to an enum definition.
57    ENUM,
58
59    /// Location adjacent to an enum value definition.
60    ENUM_VALUE,
61
62    /// Location adjacent to an input object type definition.
63    INPUT_OBJECT,
64
65    /// Location adjacent to an input object field definition.
66    INPUT_FIELD_DEFINITION,
67}
68
69// Traits for compile time checking if location at which directive is called is
70// supported by directives definition Would be nice to auto generate traits from
71// variants of __DirectiveLocation
72#[doc(hidden)]
73#[allow(non_camel_case_types)]
74pub mod location_traits {
75    pub trait Directive_At_FIELD_DEFINITION {
76        fn check() {}
77    }
78
79    pub trait Directive_At_OBJECT {
80        fn check() {}
81    }
82
83    pub trait Directive_At_INPUT_FIELD_DEFINITION {
84        fn check() {}
85    }
86
87    pub trait Directive_At_ARGUMENT_DEFINITION {
88        fn check() {}
89    }
90
91    pub trait Directive_At_INPUT_OBJECT {
92        fn check() {}
93    }
94
95    pub trait Directive_At_INTERFACE {
96        fn check() {}
97    }
98
99    pub trait Directive_At_ENUM {
100        fn check() {}
101    }
102
103    pub trait Directive_At_ENUM_VALUE {
104        fn check() {}
105    }
106}
107
108pub struct __Directive<'a> {
109    pub registry: &'a registry::Registry,
110    pub visible_types: &'a HashSet<&'a str>,
111    pub directive: &'a registry::MetaDirective,
112}
113
114/// A Directive provides a way to describe alternate runtime execution and type
115/// validation behavior in a GraphQL document.
116///
117/// In some cases, you need to provide options to alter GraphQL's execution
118/// behavior in ways field arguments will not suffice, such as conditionally
119/// including or skipping a field. Directives provide this by describing
120/// additional information to the executor.
121#[Object(internal, name = "__Directive")]
122impl<'a> __Directive<'a> {
123    #[inline]
124    async fn name(&self) -> &str {
125        &self.directive.name
126    }
127
128    #[inline]
129    async fn description(&self) -> Option<&str> {
130        self.directive.description.as_deref()
131    }
132
133    #[inline]
134    async fn locations(&self) -> &Vec<__DirectiveLocation> {
135        &self.directive.locations
136    }
137
138    async fn args(
139        &self,
140        #[graphql(default = false)] include_deprecated: bool,
141    ) -> Vec<__InputValue<'a>> {
142        self.directive
143            .args
144            .values()
145            .filter(|input_value| include_deprecated || !input_value.deprecation.is_deprecated())
146            .map(|input_value| __InputValue {
147                registry: self.registry,
148                visible_types: self.visible_types,
149                input_value,
150            })
151            .collect()
152    }
153
154    #[inline]
155    async fn is_repeatable(&self) -> bool {
156        self.directive.is_repeatable
157    }
158}