bluejay_validator/executable/document/rules/
fragments_must_be_used.rs

1use crate::executable::{
2    document::{Error, Path, Rule, Visitor},
3    Cache,
4};
5use bluejay_core::definition::{SchemaDefinition, TypeDefinitionReference};
6use bluejay_core::executable::{ExecutableDocument, FragmentDefinition, FragmentSpread};
7use std::collections::BTreeMap;
8
9pub struct FragmentsMustBeUsed<'a, E: ExecutableDocument> {
10    unused_fragment_definitions: BTreeMap<&'a str, &'a E::FragmentDefinition>,
11}
12
13impl<'a, E: ExecutableDocument, S: SchemaDefinition> Visitor<'a, E, S>
14    for FragmentsMustBeUsed<'a, E>
15{
16    fn new(executable_document: &'a E, _: &'a S, _: &'a Cache<'a, E, S>) -> Self {
17        Self {
18            unused_fragment_definitions: BTreeMap::from_iter(
19                executable_document
20                    .fragment_definitions()
21                    .map(|fd| (fd.name(), fd)),
22            ),
23        }
24    }
25
26    fn visit_fragment_spread(
27        &mut self,
28        fragment_spread: &'a <E as ExecutableDocument>::FragmentSpread,
29        _scoped_type: TypeDefinitionReference<'a, S::TypeDefinition>,
30        _path: &Path<'a, E>,
31    ) {
32        self.unused_fragment_definitions
33            .remove(fragment_spread.name());
34    }
35}
36
37impl<'a, E: ExecutableDocument + 'a, S: SchemaDefinition + 'a> Rule<'a, E, S>
38    for FragmentsMustBeUsed<'a, E>
39{
40    type Error = Error<'a, E, S>;
41    type Errors = std::iter::Map<
42        std::collections::btree_map::IntoValues<&'a str, &'a E::FragmentDefinition>,
43        fn(&'a E::FragmentDefinition) -> Error<'a, E, S>,
44    >;
45
46    fn into_errors(self) -> Self::Errors {
47        self.unused_fragment_definitions
48            .into_values()
49            .map(|fragment_definition| Error::FragmentDefinitionUnused {
50                fragment_definition,
51            })
52    }
53}