aldrin_parser/ast/
named_ref.rs

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