aldrin_parser/error/
expected_const_int_found_string.rs1use super::Error;
2use crate::ast::{ConstValue, NamedRef, NamedRefKind};
3use crate::diag::{Diagnostic, DiagnosticKind, Formatted, Formatter};
4use crate::validate::Validate;
5use crate::{util, Parsed};
6
7#[derive(Debug)]
8pub struct ExpectedConstIntFoundString {
9 schema_name: String,
10 named_ref: NamedRef,
11 candidate: Option<String>,
12}
13
14impl ExpectedConstIntFoundString {
15 pub(crate) fn validate(named_ref: &NamedRef, validate: &mut Validate) {
16 let (schema, ident) = match named_ref.kind() {
17 NamedRefKind::Intern(ident) => (validate.get_current_schema(), ident),
18
19 NamedRefKind::Extern(schema, ident) => {
20 let Some(schema) = validate.get_schema(schema.value()) else {
21 return;
22 };
23
24 (schema, ident)
25 }
26 };
27
28 let mut found = false;
29 for def in schema.definitions() {
30 if def.name().value() == ident.value() {
31 let Some(const_def) = def.as_const() else {
32 return;
33 };
34
35 if matches!(const_def.value(), ConstValue::String(_)) {
36 found = true;
37 } else {
38 return;
39 }
40 }
41 }
42
43 if found {
44 let candidate =
45 util::did_you_mean_const_int(schema, ident.value()).map(ToOwned::to_owned);
46
47 validate.add_error(Self {
48 schema_name: validate.schema_name().to_owned(),
49 named_ref: named_ref.clone(),
50 candidate,
51 });
52 }
53 }
54
55 pub fn named_ref(&self) -> &NamedRef {
56 &self.named_ref
57 }
58}
59
60impl Diagnostic for ExpectedConstIntFoundString {
61 fn kind(&self) -> DiagnosticKind {
62 DiagnosticKind::Error
63 }
64
65 fn schema_name(&self) -> &str {
66 &self.schema_name
67 }
68
69 fn format<'a>(&'a self, parsed: &'a Parsed) -> Formatted<'a> {
70 let mut fmt = Formatter::new(
71 self,
72 format!(
73 "expected integer constant; found string constant `{}`",
74 self.named_ref.ident().value()
75 ),
76 );
77
78 if let Some(schema) = parsed.get_schema(&self.schema_name) {
79 fmt.main_block(
80 schema,
81 self.named_ref.span().from,
82 self.named_ref.span(),
83 "integer constant expected here",
84 );
85 }
86
87 if let Some(ref candidate) = self.candidate {
88 match self.named_ref.schema() {
89 Some(schema) => {
90 fmt.help(format!("did you mean `{}::{candidate}`?", schema.value()));
91 }
92
93 None => {
94 fmt.help(format!("did you mean `{candidate}`?"));
95 }
96 }
97 }
98
99 fmt.format()
100 }
101}
102
103impl From<ExpectedConstIntFoundString> for Error {
104 fn from(e: ExpectedConstIntFoundString) -> Self {
105 Self::ExpectedConstIntFoundString(e)
106 }
107}