graphql_federated_graph/directives/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
mod authorized;
mod complexity_control;
mod deprecated;
mod federation;

use crate::{ListSize, StringId, Value};

pub use self::{
    complexity_control::{CostDirective, ListSizeDirective},
    deprecated::DeprecatedDirective,
};
pub use authorized::*;
pub use federation::*;

#[derive(PartialEq, PartialOrd, Clone, Debug)]
pub enum Directive {
    Authenticated,
    Deprecated {
        reason: Option<StringId>,
    },
    Inaccessible,
    Policy(Vec<Vec<StringId>>),
    RequiresScopes(Vec<Vec<StringId>>),
    Cost {
        weight: i32,
    },
    JoinField(JoinFieldDirective),
    JoinType(JoinTypeDirective),
    JoinUnionMember(JoinUnionMemberDirective),
    JoinImplements(JoinImplementsDirective),
    Authorized(AuthorizedDirective),
    Other {
        name: StringId,
        arguments: Vec<(StringId, Value)>,
    },
    ListSize(ListSize),
}

impl From<JoinFieldDirective> for Directive {
    fn from(d: JoinFieldDirective) -> Self {
        Self::JoinField(d)
    }
}

impl From<JoinTypeDirective> for Directive {
    fn from(d: JoinTypeDirective) -> Self {
        Self::JoinType(d)
    }
}

impl Directive {
    pub fn as_join_field(&self) -> Option<&JoinFieldDirective> {
        match self {
            Directive::JoinField(d) => Some(d),
            _ => None,
        }
    }

    pub fn as_join_field_mut(&mut self) -> Option<&mut JoinFieldDirective> {
        match self {
            Directive::JoinField(d) => Some(d),
            _ => None,
        }
    }

    pub fn as_join_type(&self) -> Option<&JoinTypeDirective> {
        match self {
            Directive::JoinType(d) => Some(d),
            _ => None,
        }
    }

    pub fn as_join_union_member(&self) -> Option<&JoinUnionMemberDirective> {
        match self {
            Directive::JoinUnionMember(d) => Some(d),
            _ => None,
        }
    }

    pub fn as_join_implements(&self) -> Option<&JoinImplementsDirective> {
        match self {
            Directive::JoinImplements(d) => Some(d),
            _ => None,
        }
    }
}

#[cfg(test)]
/// Helper for tests
fn parse_directive<T>(input: &str) -> Result<T, cynic_parser_deser::Error>
where
    T: cynic_parser_deser::ValueDeserializeOwned,
{
    let doc = directive_test_document(input);
    parse_from_test_document(&doc)
}

#[cfg(test)]
/// Helper for tests where the directive has a lifetime
///
/// Should be used with parse_from_test_document
fn directive_test_document(directive: &str) -> cynic_parser::TypeSystemDocument {
    cynic_parser::parse_type_system_document(&format!("type Object {directive} {{name: String}}")).unwrap()
}

#[cfg(test)]
/// Helper for tests where the directive has a lifetime
///
/// Should be used with the document from directive_test_document
fn parse_from_test_document<'a, T>(doc: &'a cynic_parser::TypeSystemDocument) -> Result<T, cynic_parser_deser::Error>
where
    T: cynic_parser_deser::ValueDeserialize<'a>,
{
    use cynic_parser::type_system::Definition;
    use cynic_parser_deser::ConstDeserializer;
    let Definition::Type(definition) = doc.definitions().next().unwrap() else {
        unreachable!()
    };
    definition.directives().next().unwrap().deserialize::<T>()
}