aldrin_parser/ast/
named_ref.rs1use 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(); 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}