aldrin_parser/ast/
named_ref.rs

1use super::Ident;
2use crate::error::MissingImport;
3use crate::grammar::Rule;
4use crate::validate::Validate;
5use crate::Span;
6use pest::iterators::Pair;
7use std::fmt;
8
9#[derive(Debug, Clone)]
10pub struct NamedRef {
11    span: Span,
12    kind: NamedRefKind,
13}
14
15impl NamedRef {
16    pub(crate) fn parse(pair: Pair<Rule>) -> Self {
17        assert_eq!(pair.as_rule(), Rule::named_ref);
18
19        let span = Span::from_pair(&pair);
20
21        let mut pairs = pair.into_inner();
22        let pair = pairs.next().unwrap();
23        let kind = NamedRefKind::parse(pair);
24
25        Self { span, kind }
26    }
27
28    pub(crate) fn dummy_intern(ident: Ident) -> Self {
29        Self {
30            span: Span::dummy(),
31            kind: NamedRefKind::Intern(ident),
32        }
33    }
34
35    pub(crate) fn validate(&self, validate: &mut Validate) {
36        self.kind.validate(validate);
37    }
38
39    pub fn span(&self) -> Span {
40        self.span
41    }
42
43    pub fn kind(&self) -> &NamedRefKind {
44        &self.kind
45    }
46
47    pub fn schema(&self) -> Option<&Ident> {
48        self.kind.schema()
49    }
50
51    pub fn ident(&self) -> &Ident {
52        self.kind.ident()
53    }
54}
55
56#[derive(Debug, Clone)]
57pub enum NamedRefKind {
58    Intern(Ident),
59    Extern(Ident, Ident),
60}
61
62impl NamedRefKind {
63    fn parse(pair: Pair<Rule>) -> Self {
64        match pair.as_rule() {
65            Rule::ident => Self::Intern(Ident::parse(pair)),
66
67            Rule::external_ref => {
68                let mut pairs = pair.into_inner();
69                let pair = pairs.next().unwrap();
70                let schema_name = Ident::parse(pair);
71                pairs.next().unwrap(); // Skip ::.
72                let ident = Ident::parse(pairs.next().unwrap());
73
74                Self::Extern(schema_name, ident)
75            }
76
77            _ => unreachable!(),
78        }
79    }
80
81    fn validate(&self, validate: &mut Validate) {
82        match self {
83            Self::Intern(ty) => {
84                ty.validate(false, validate);
85            }
86
87            Self::Extern(schema, ty) => {
88                MissingImport::validate(schema, validate);
89                ty.validate(false, validate);
90            }
91        }
92    }
93
94    pub fn schema(&self) -> Option<&Ident> {
95        match self {
96            Self::Intern(_) => None,
97            Self::Extern(schema, _) => Some(schema),
98        }
99    }
100
101    pub fn ident(&self) -> &Ident {
102        match self {
103            Self::Intern(ident) => ident,
104            Self::Extern(_, ident) => ident,
105        }
106    }
107}
108
109impl fmt::Display for NamedRefKind {
110    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111        match self {
112            Self::Intern(ident) => write!(f, "{}", ident.value()),
113            Self::Extern(schema, ident) => write!(f, "{}::{}", schema.value(), ident.value()),
114        }
115    }
116}