graphql_federated_graph/directives/
mod.rs1mod authorized;
2mod complexity_control;
3mod deprecated;
4mod extension;
5mod federation;
6mod require;
7
8use crate::{ListSize, StringId, SubgraphId, Value};
9
10pub use self::{
11 complexity_control::{CostDirective, ListSizeDirective},
12 deprecated::DeprecatedDirective,
13 require::RequireDirective,
14};
15pub use authorized::*;
16pub use extension::*;
17pub use federation::*;
18
19#[derive(PartialEq, PartialOrd, Clone, Debug)]
20pub enum Directive {
21 Authenticated,
22 CompositeLookup {
23 graph: SubgraphId,
24 },
25 CompositeDerive {
26 graph: SubgraphId,
27 },
28 CompositeRequire {
29 graph: SubgraphId,
30 field: StringId,
31 },
32 CompositeIs {
33 graph: SubgraphId,
34 field: StringId,
35 },
36 Deprecated {
37 reason: Option<StringId>,
38 },
39 OneOf,
40 Inaccessible,
41 Policy(Vec<Vec<StringId>>),
42 RequiresScopes(Vec<Vec<StringId>>),
43 Cost {
44 weight: i32,
45 },
46 JoinGraph(JoinGraphDirective),
47 JoinField(JoinFieldDirective),
48 JoinType(JoinTypeDirective),
49 JoinUnionMember(JoinUnionMemberDirective),
50 JoinImplements(JoinImplementsDirective),
51 Authorized(AuthorizedDirective),
52 Other {
53 name: StringId,
54 arguments: Vec<(StringId, Value)>,
55 },
56 ListSize(ListSize),
57
58 ExtensionDirective(ExtensionDirective),
59}
60
61impl From<JoinFieldDirective> for Directive {
62 fn from(d: JoinFieldDirective) -> Self {
63 Self::JoinField(d)
64 }
65}
66
67impl From<JoinTypeDirective> for Directive {
68 fn from(d: JoinTypeDirective) -> Self {
69 Self::JoinType(d)
70 }
71}
72
73impl Directive {
74 pub fn as_join_field(&self) -> Option<&JoinFieldDirective> {
75 match self {
76 Directive::JoinField(d) => Some(d),
77 _ => None,
78 }
79 }
80
81 pub fn as_join_field_mut(&mut self) -> Option<&mut JoinFieldDirective> {
82 match self {
83 Directive::JoinField(d) => Some(d),
84 _ => None,
85 }
86 }
87
88 pub fn as_join_type(&self) -> Option<&JoinTypeDirective> {
89 match self {
90 Directive::JoinType(d) => Some(d),
91 _ => None,
92 }
93 }
94
95 pub fn as_join_union_member(&self) -> Option<&JoinUnionMemberDirective> {
96 match self {
97 Directive::JoinUnionMember(d) => Some(d),
98 _ => None,
99 }
100 }
101
102 pub fn as_extension_directive(&self) -> Option<&ExtensionDirective> {
103 match self {
104 Directive::ExtensionDirective(d) => Some(d),
105 _ => None,
106 }
107 }
108
109 pub fn as_join_implements(&self) -> Option<&JoinImplementsDirective> {
110 match self {
111 Directive::JoinImplements(d) => Some(d),
112 _ => None,
113 }
114 }
115}
116
117#[cfg(test)]
118fn parse_directive<T>(input: &str) -> Result<T, cynic_parser_deser::Error>
120where
121 T: cynic_parser_deser::ValueDeserializeOwned,
122{
123 let doc = directive_test_document(input);
124 parse_from_test_document(&doc)
125}
126
127#[cfg(test)]
128fn directive_test_document(directive: &str) -> cynic_parser::TypeSystemDocument {
132 cynic_parser::parse_type_system_document(&format!("type Object {directive} {{name: String}}")).unwrap()
133}
134
135#[cfg(test)]
136fn parse_from_test_document<'a, T>(doc: &'a cynic_parser::TypeSystemDocument) -> Result<T, cynic_parser_deser::Error>
140where
141 T: cynic_parser_deser::ValueDeserialize<'a>,
142{
143 use cynic_parser::type_system::Definition;
144 use cynic_parser_deser::ConstDeserializer;
145 let Definition::Type(definition) = doc.definitions().next().unwrap() else {
146 unreachable!()
147 };
148 definition.directives().next().unwrap().deserialize::<T>()
149}