graphql_federated_graph/directives/
mod.rs

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