aldrin_parser/error/
duplicate_enum_variant.rs1use super::Error;
2use crate::ast::{EnumVariant, Ident};
3use crate::diag::{Diagnostic, DiagnosticKind, Formatted, Formatter};
4use crate::validate::Validate;
5use crate::{util, Parsed, Span};
6
7#[derive(Debug)]
8pub struct DuplicateEnumVariant {
9 schema_name: String,
10 duplicate: Ident,
11 first: Span,
12 enum_span: Span,
13 enum_ident: Option<Ident>,
14}
15
16impl DuplicateEnumVariant {
17 pub(crate) fn validate(
18 vars: &[EnumVariant],
19 fallback: Option<&Ident>,
20 enum_span: Span,
21 ident: Option<&Ident>,
22 validate: &mut Validate,
23 ) {
24 util::find_duplicates(
25 vars,
26 |var| var.name().value(),
27 |duplicate, first| {
28 validate.add_error(Self {
29 schema_name: validate.schema_name().to_owned(),
30 duplicate: duplicate.name().clone(),
31 first: first.name().span(),
32 enum_span,
33 enum_ident: ident.cloned(),
34 })
35 },
36 );
37
38 if let Some(fallback) = fallback {
39 for var in vars {
40 if fallback.value() == var.name().value() {
41 validate.add_error(Self {
42 schema_name: validate.schema_name().to_owned(),
43 duplicate: fallback.clone(),
44 first: var.span(),
45 enum_span,
46 enum_ident: ident.cloned(),
47 });
48
49 break;
50 }
51 }
52 }
53 }
54
55 pub fn duplicate(&self) -> &Ident {
56 &self.duplicate
57 }
58
59 pub fn first(&self) -> Span {
60 self.first
61 }
62
63 pub fn enum_span(&self) -> Span {
64 self.enum_span
65 }
66
67 pub fn enum_ident(&self) -> Option<&Ident> {
68 self.enum_ident.as_ref()
69 }
70}
71
72impl Diagnostic for DuplicateEnumVariant {
73 fn kind(&self) -> DiagnosticKind {
74 DiagnosticKind::Error
75 }
76
77 fn schema_name(&self) -> &str {
78 &self.schema_name
79 }
80
81 fn format<'a>(&'a self, parsed: &'a Parsed) -> Formatted<'a> {
82 let mut fmt = if let Some(ref ident) = self.enum_ident {
83 Formatter::new(
84 self,
85 format!(
86 "duplicate variant `{}` in enum `{}`",
87 self.duplicate.value(),
88 ident.value()
89 ),
90 )
91 } else {
92 Formatter::new(
93 self,
94 format!(
95 "duplicate variant `{}` in inline enum",
96 self.duplicate.value()
97 ),
98 )
99 };
100
101 if let Some(schema) = parsed.get_schema(&self.schema_name) {
102 fmt.main_block(
103 schema,
104 self.duplicate.span().from,
105 self.duplicate.span(),
106 "duplicate defined here",
107 )
108 .info_block(schema, self.first.from, self.first, "first defined here");
109 }
110
111 fmt.format()
112 }
113}
114
115impl From<DuplicateEnumVariant> for Error {
116 fn from(e: DuplicateEnumVariant) -> Self {
117 Self::DuplicateEnumVariant(e)
118 }
119}