graphql_federated_graph/directives/
require.rs

1use cynic_parser_deser::{ConstDeserializer as _, ValueDeserialize};
2
3/// The composite spec `@require` directive, but in the context of a federated schema. Not to be confused with the federation `@requires` directive.
4///
5/// Reference: https://github.com/graphql/composite-schemas-spec/blob/main/spec/Section%202%20--%20Source%20Schema.md#require
6pub struct RequireDirective<'a> {
7    pub field: &'a str,
8}
9
10impl<'a> ValueDeserialize<'a> for RequireDirective<'a> {
11    fn deserialize(input: cynic_parser_deser::DeserValue<'a>) -> Result<Self, cynic_parser_deser::Error> {
12        let cynic_parser_deser::DeserValue::Object(obj) = input else {
13            return Err(cynic_parser_deser::Error::unexpected_type(
14                cynic_parser_deser::value::ValueType::Object,
15                input,
16            ));
17        };
18
19        let mut field_field = None;
20
21        for field in obj.fields() {
22            match field.name() {
23                "field" => field_field = Some(field.value().deserialize()?),
24                other => {
25                    return Err(cynic_parser_deser::Error::UnknownField {
26                        name: other.to_string(),
27                        field_type: field.value().into(),
28                        field_span: field.name_span(),
29                    });
30                }
31            }
32        }
33
34        let Some(field) = field_field else {
35            return Err(cynic_parser_deser::Error::MissingField {
36                name: "field".to_owned(),
37                object_span: obj.span(),
38            });
39        };
40
41        Ok(RequireDirective { field })
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use crate::directives::{directive_test_document, parse_from_test_document};
49
50    #[test]
51    fn test_require_directive() {
52        let doc = directive_test_document("@require(field: \"someField\")");
53        let value = parse_from_test_document::<RequireDirective<'_>>(&doc).unwrap();
54
55        assert_eq!(value.field, "someField");
56    }
57}