graphql_composition/
diagnostics.rs

1/// Warnings and errors produced by composition.
2#[derive(Default, Debug)]
3pub struct Diagnostics(Vec<Diagnostic>);
4
5impl Diagnostics {
6    /// Is any of the diagnostics fatal, i.e. a hard error?
7    pub fn any_fatal(&self) -> bool {
8        self.0.iter().any(|diagnostic| diagnostic.is_fatal)
9    }
10
11    /// Is there any diagnostic warning or error
12    pub fn is_empty(&self) -> bool {
13        self.0.is_empty()
14    }
15
16    /// Iterate non-fatal diagnostics.
17    pub fn iter_warnings(&self) -> impl Iterator<Item = &str> {
18        self.0
19            .iter()
20            .filter(|diagnostic| !diagnostic.is_fatal)
21            .map(|diagnostic| diagnostic.message.as_str())
22    }
23
24    /// Iterate fatal diagnostics.
25    pub fn iter_errors(&self) -> impl Iterator<Item = &str> {
26        self.0
27            .iter()
28            .filter(|diagnostic| diagnostic.is_fatal)
29            .map(|diagnostic| diagnostic.message.as_str())
30    }
31
32    pub(crate) fn clone_all_from(&mut self, other: &Diagnostics) {
33        self.0.extend(other.0.iter().cloned())
34    }
35
36    /// Iterate over all diagnostic messages.
37    pub fn iter_messages(&self) -> impl Iterator<Item = &str> {
38        self.0.iter().map(|diagnostic| diagnostic.message.as_str())
39    }
40
41    pub(crate) fn push_fatal(&mut self, message: String) {
42        self.0.push(Diagnostic {
43            message,
44            is_fatal: true,
45        });
46    }
47
48    pub(crate) fn push_warning(&mut self, message: String) {
49        self.0.push(Diagnostic {
50            message,
51            is_fatal: false,
52        });
53    }
54}
55
56/// A composition diagnostic.
57#[derive(Debug, Clone)]
58pub(crate) struct Diagnostic {
59    message: String,
60    /// Should this diagnostic be interpreted as a composition failure?
61    is_fatal: bool,
62}