aldrin_parser/error/
expected_const_int_found_service.rs

1use 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}