aldrin_parser/ast/
named_ref.rs1use super::Ident;
2use crate::Span;
3use crate::error::MissingImport;
4use crate::grammar::Rule;
5use crate::validate::Validate;
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 #[expect(clippy::wildcard_enum_match_arm)]
65 match pair.as_rule() {
66 Rule::ident => Self::Intern(Ident::parse(&pair)),
67
68 Rule::external_ref => {
69 let mut pairs = pair.into_inner();
70 let pair = pairs.next().unwrap();
71 let schema_name = Ident::parse(&pair);
72 pairs.next().unwrap(); let ident = Ident::parse(&pairs.next().unwrap());
74
75 Self::Extern(schema_name, ident)
76 }
77
78 _ => unreachable!(),
79 }
80 }
81
82 fn validate(&self, validate: &mut Validate) {
83 match self {
84 Self::Intern(ty) => {
85 ty.validate(false, validate);
86 }
87
88 Self::Extern(schema, ty) => {
89 MissingImport::validate(schema, validate);
90 ty.validate(false, validate);
91 }
92 }
93 }
94
95 pub fn schema(&self) -> Option<&Ident> {
96 match self {
97 Self::Intern(_) => None,
98 Self::Extern(schema, _) => Some(schema),
99 }
100 }
101
102 pub fn ident(&self) -> &Ident {
103 match self {
104 Self::Intern(ident) | 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}