cynic_parser/executable/
types.rs

1use crate::{
2    common::{TypeWrappers, TypeWrappersIter, WrappingType},
3    AstLookup, Span,
4};
5
6use super::{
7    ids::{StringId, TypeId},
8    ExecutableId, ReadContext,
9};
10
11pub struct TypeRecord {
12    pub name: StringId,
13    pub name_start: usize,
14    pub wrappers: TypeWrappers,
15    pub span: Span,
16}
17
18#[derive(Clone, Copy)]
19pub struct Type<'a>(ReadContext<'a, TypeId>);
20
21impl PartialEq for Type<'_> {
22    fn eq(&self, other: &Self) -> bool {
23        self.name() == other.name() && self.wrappers().eq(other.wrappers())
24    }
25}
26
27impl Eq for Type<'_> {}
28
29impl<'a> Type<'a> {
30    pub fn name(&self) -> &'a str {
31        self.0
32            .document
33            .lookup(self.0.document.lookup(self.0.id).name)
34    }
35
36    /// The span of this types named type
37    pub fn name_span(&self) -> Span {
38        let record = self.0.document.lookup(self.0.id);
39
40        Span::new(
41            record.name_start,
42            record.name_start + self.0.document.lookup(record.name).len(),
43        )
44    }
45
46    /// The wrapper types from the outermost to innermost
47    pub fn wrappers(&self) -> TypeWrappersIter {
48        self.0.document.lookup(self.0.id).wrappers.iter()
49    }
50
51    /// The span of the the type, including any wrapppers
52    pub fn span(&self) -> Span {
53        self.0.document.lookup(self.0.id).span
54    }
55}
56
57impl std::fmt::Display for Type<'_> {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        let ast = &self.0.document;
60
61        let TypeRecord { name, wrappers, .. } = ast.lookup(self.0.id);
62
63        let wrappers = wrappers.iter().collect::<Vec<_>>();
64        for wrapping in &wrappers {
65            if let WrappingType::List = wrapping {
66                write!(f, "[")?;
67            }
68        }
69        write!(f, "{}", ast.lookup(*name))?;
70        for wrapping in wrappers.iter().rev() {
71            match wrapping {
72                WrappingType::NonNull => write!(f, "!")?,
73                WrappingType::List => write!(f, "]")?,
74            }
75        }
76
77        Ok(())
78    }
79}
80
81impl std::fmt::Debug for Type<'_> {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        f.debug_tuple("Type").field(&self.to_string()).finish()
84    }
85}
86
87impl ExecutableId for TypeId {
88    type Reader<'a> = Type<'a>;
89
90    fn read(self, document: &super::ExecutableDocument) -> Self::Reader<'_> {
91        Type(ReadContext { id: self, document })
92    }
93}