bluejay_validator/executable/document/
path.rs

1use bluejay_core::{
2    executable::{ExecutableDocument, FragmentDefinition, OperationDefinition},
3    Indexable,
4};
5use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
6use std::hash::{Hash, Hasher};
7
8pub struct Path<'a, E: ExecutableDocument> {
9    root: PathRoot<'a, E>,
10    members: Vec<&'a E::Selection>,
11}
12
13impl<E: ExecutableDocument> Clone for Path<'_, E> {
14    fn clone(&self) -> Self {
15        Self {
16            root: self.root,
17            members: self.members.clone(),
18        }
19    }
20}
21
22impl<'a, E: ExecutableDocument> Path<'a, E> {
23    pub fn new(root: PathRoot<'a, E>) -> Self {
24        Self {
25            root,
26            members: Vec::new(),
27        }
28    }
29
30    pub fn root(&self) -> &PathRoot<'a, E> {
31        &self.root
32    }
33
34    pub fn with_selection(&self, selection: &'a E::Selection) -> Self {
35        let mut clone = self.clone();
36        clone.members.push(selection);
37        clone
38    }
39
40    pub fn members(&self) -> &[&'a E::Selection] {
41        &self.members
42    }
43}
44
45pub enum PathRoot<'a, E: ExecutableDocument> {
46    Operation(&'a E::OperationDefinition),
47    Fragment(&'a E::FragmentDefinition),
48}
49
50impl<'a, E: ExecutableDocument + 'a> PathRoot<'a, E> {
51    pub fn name(&self) -> Option<&'a str> {
52        match self {
53            Self::Operation(o) => o.as_ref().name(),
54            Self::Fragment(f) => Some(f.name()),
55        }
56    }
57}
58
59impl<E: ExecutableDocument> Clone for PathRoot<'_, E> {
60    fn clone(&self) -> Self {
61        *self
62    }
63}
64
65impl<E: ExecutableDocument> Copy for PathRoot<'_, E> {}
66
67impl<E: ExecutableDocument> Hash for PathRoot<'_, E> {
68    fn hash<H: Hasher>(&self, state: &mut H) {
69        match self {
70            Self::Operation(o) => o.id().hash(state),
71            Self::Fragment(f) => f.id().hash(state),
72        }
73    }
74}
75
76impl<E: ExecutableDocument> PartialEq for PathRoot<'_, E> {
77    fn eq(&self, other: &Self) -> bool {
78        match (self, other) {
79            (Self::Operation(l), Self::Operation(r)) => l.id() == r.id(),
80            (Self::Fragment(l), Self::Fragment(r)) => l.id() == r.id(),
81            _ => false,
82        }
83    }
84}
85
86impl<E: ExecutableDocument> Eq for PathRoot<'_, E> {}
87
88impl<E: ExecutableDocument> Ord for PathRoot<'_, E> {
89    fn cmp(&self, other: &Self) -> Ordering {
90        match (self, other) {
91            (Self::Fragment(l), Self::Fragment(r)) => l.id().cmp(r.id()),
92            (Self::Fragment(_), Self::Operation(_)) => Ordering::Greater,
93            (Self::Operation(_), Self::Fragment(_)) => Ordering::Less,
94            (Self::Operation(l), Self::Operation(r)) => l.id().cmp(r.id()),
95        }
96    }
97}
98
99impl<E: ExecutableDocument> PartialOrd for PathRoot<'_, E> {
100    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101        Some(self.cmp(other))
102    }
103}