aldrin_parser/error/
expected_const_int_found_service.rs1use super::Error;
2use crate::ast::{Definition, NamedRef, NamedRefKind};
3use crate::diag::{Diagnostic, DiagnosticKind, Formatted, Formatter};
4use crate::validate::Validate;
5use crate::{util, Parsed};
6
7#[derive(Debug)]
8pub struct ExpectedConstIntFoundService {
9 schema_name: String,
10 named_ref: NamedRef,
11 candidate: Option<String>,
12}
13
14impl ExpectedConstIntFoundService {
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 match def {
32 Definition::Service(_) => found = true,
33 Definition::Struct(_) | Definition::Enum(_) | Definition::Const(_) => return,
34 }
35 }
36 }
37
38 if found {
39 let candidate =
40 util::did_you_mean_const_int(schema, ident.value()).map(ToOwned::to_owned);
41
42 validate.add_error(Self {
43 schema_name: validate.schema_name().to_owned(),
44 named_ref: named_ref.clone(),
45 candidate,
46 });
47 }
48 }
49
50 pub fn named_ref(&self) -> &NamedRef {
51 &self.named_ref
52 }
53}
54
55impl Diagnostic for ExpectedConstIntFoundService {
56 fn kind(&self) -> DiagnosticKind {
57 DiagnosticKind::Error
58 }
59
60 fn schema_name(&self) -> &str {
61 &self.schema_name
62 }
63
64 fn format<'a>(&'a self, parsed: &'a Parsed) -> Formatted<'a> {
65 let mut fmt = Formatter::new(
66 self,
67 format!(
68 "expected integer constant; found service `{}`",
69 self.named_ref.ident().value()
70 ),
71 );
72
73 if let Some(schema) = parsed.get_schema(&self.schema_name) {
74 fmt.main_block(
75 schema,
76 self.named_ref.span().from,
77 self.named_ref.span(),
78 "integer constant expected here",
79 );
80 }
81
82 if let Some(ref candidate) = self.candidate {
83 match self.named_ref.schema() {
84 Some(schema) => {
85 fmt.help(format!("did you mean `{}::{candidate}`?", schema.value()));
86 }
87
88 None => {
89 fmt.help(format!("did you mean `{candidate}`?"));
90 }
91 }
92 }
93
94 fmt.format()
95 }
96}
97
98impl From<ExpectedConstIntFoundService> for Error {
99 fn from(e: ExpectedConstIntFoundService) -> Self {
100 Self::ExpectedConstIntFoundService(e)
101 }
102}