sdml_errors/diagnostics/
codes.rs

1/*!
2The [`ErrorCode`] type represents the set of conditions reported by the Diagnostics system.
3 */
4
5use codespan_reporting::diagnostic::Severity;
6use std::fmt::Display;
7
8// ------------------------------------------------------------------------------------------------
9// Public Types
10// ------------------------------------------------------------------------------------------------
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
13#[repr(u32)]
14pub enum ErrorCode {
15    // --------------------------------------------------------------------------------------------
16    // Bugs
17    // --------------------------------------------------------------------------------------------
18    TreeSitterErrorNode = 1,
19    TreeSitterUnexpectedNode = 2,
20    TreeSitterMissingNode = 3,
21    TreeSitterMissingVariable = 4,
22
23    // --------------------------------------------------------------------------------------------
24    // Errors
25    // --------------------------------------------------------------------------------------------
26    ModuleNotFound = 100,
27    ImportedModuleNotFound = 101,
28    ModuleVersionNotFound = 102,
29    ModuleVersionMismatch = 103,
30    DuplicateDefinitionName = 104,
31    DuplicateMemberName = 105,
32    DuplicateVariantName = 106,
33    InvalidIdentifier = 107,
34    InvalidLanguageTag = 108,
35    InvalidValueForType = 109,
36    InvalidModuleBaseUrl = 110,
37    InvalidModuleVersionUrl = 112,
38    DefinitionNotFound = 113,
39    TypeDefinitionNotFound = 114,
40    DatatypeInvalidBase = 115,
41    TypeClassIncompatible = 116,
42    PropertyIncompatible = 117,
43    RdfDefinitionIncompatible = 118,
44    FeatureSetNotUnion = 119, // <<< deprecated
45    PropertyReferenceNotProperty = 120,
46    LibraryDefinitionNotAllowed = 121,
47    DimensionParentNotEntity = 122,
48    SourceEntityNotEntity = 123,
49    SourceEntityMissingMember = 124,
50
51    // --------------------------------------------------------------------------------------------
52    // Warnings
53    // --------------------------------------------------------------------------------------------
54    DuplicateModuleImport = 301,
55    DuplicateDefinitionImport = 302,
56    ValidationIncomplete = 303,
57    ModuleVersionInfoEmpty = 304,
58    DeprecatedTermUsed = 305,
59
60    // --------------------------------------------------------------------------------------------
61    // Informational
62    // --------------------------------------------------------------------------------------------
63    IncompleteModule = 500,
64    IncompleteDefinition = 501,
65    IncompleteMember = 502,
66    StringWithoutLanguage = 503,
67    UnconstrainedDatatype = 504,
68    DoubleUnderscoredIdentifier = 505,
69    IdentifierNotPreferredCase = 506,
70}
71
72// ------------------------------------------------------------------------------------------------
73// Implementations
74// ------------------------------------------------------------------------------------------------
75
76impl Display for ErrorCode {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        write!(
79            f,
80            "{}{:04}",
81            match self.severity() {
82                Severity::Bug => "B",
83                Severity::Error => "E",
84                Severity::Warning => "W",
85                Severity::Note => "I",
86                Severity::Help => "H",
87            },
88            self.number()
89        )
90    }
91}
92
93impl ErrorCode {
94    /// Return the numeric value for this code.
95    #[inline(always)]
96    pub fn number(&self) -> u32 {
97        *self as u32
98    }
99
100    /// Return the severity of this code.
101    #[inline(always)]
102    pub fn severity(&self) -> Severity {
103        match self {
104            Self::TreeSitterErrorNode
105            | Self::TreeSitterUnexpectedNode
106            | Self::TreeSitterMissingNode
107            | Self::TreeSitterMissingVariable => Severity::Bug,
108            Self::ModuleNotFound
109            | Self::ImportedModuleNotFound
110            | Self::ModuleVersionNotFound
111            | Self::ModuleVersionMismatch
112            | Self::DuplicateDefinitionName
113            | Self::DuplicateMemberName
114            | Self::DuplicateVariantName
115            | Self::InvalidIdentifier
116            | Self::InvalidLanguageTag
117            | Self::InvalidValueForType
118            | Self::InvalidModuleBaseUrl
119            | Self::InvalidModuleVersionUrl
120            | Self::DefinitionNotFound
121            | Self::TypeDefinitionNotFound
122            | Self::DatatypeInvalidBase
123            | Self::TypeClassIncompatible
124            | Self::PropertyIncompatible
125            | Self::RdfDefinitionIncompatible
126            | Self::FeatureSetNotUnion
127            | Self::PropertyReferenceNotProperty
128            | Self::LibraryDefinitionNotAllowed
129            | Self::DimensionParentNotEntity
130            | Self::SourceEntityNotEntity
131            | Self::SourceEntityMissingMember => Severity::Error,
132            Self::DuplicateModuleImport
133            | Self::DuplicateDefinitionImport
134            | Self::ValidationIncomplete
135            | Self::ModuleVersionInfoEmpty
136            | Self::DeprecatedTermUsed => Severity::Warning,
137            Self::IncompleteModule
138            | Self::IncompleteDefinition
139            | Self::IncompleteMember
140            | Self::StringWithoutLanguage
141            | Self::UnconstrainedDatatype
142            | Self::DoubleUnderscoredIdentifier
143            | Self::IdentifierNotPreferredCase => Severity::Note,
144        }
145    }
146
147    /// Return the descriptive message for this code.
148    pub fn message(&self) -> String {
149        match self {
150            Self::TreeSitterErrorNode => i18n!("msg_treesitter_error_node"),
151            Self::TreeSitterUnexpectedNode => i18n!("msg_treesitter_unexpected_node"),
152            Self::TreeSitterMissingNode => i18n!("msg_treesitter_missing_node"),
153            Self::TreeSitterMissingVariable => i18n!("msg_treesitter_missing_variable"),
154            Self::ModuleNotFound => i18n!("msg_module_not_found"),
155            Self::ImportedModuleNotFound => i18n!("msg_imported_module_not_found"),
156            Self::ModuleVersionNotFound => i18n!("msg_module_version_not_found"),
157            Self::ModuleVersionMismatch => {
158                i18n!("msg_module_version_mismatch")
159            }
160            Self::DuplicateDefinitionName => {
161                i18n!("msg_duplicate_definition_name")
162            }
163            Self::DuplicateMemberName => {
164                i18n!("msg_duplicate_member_name")
165            }
166            Self::DuplicateVariantName => {
167                i18n!("msg_duplicate_variant_name")
168            }
169            Self::InvalidIdentifier => i18n!("msg_invalid_identifier"),
170            Self::InvalidLanguageTag => i18n!("msg_invalid_language_tag"),
171            Self::InvalidValueForType => i18n!("msg_invalid_value_for_type"),
172            Self::InvalidModuleBaseUrl => i18n!("msg_invalid_module_base_url"),
173            Self::InvalidModuleVersionUrl => i18n!("msg_invalid_module_version_url"),
174            Self::DefinitionNotFound => i18n!("msg_definition_not_found"),
175            Self::TypeDefinitionNotFound => i18n!("msg_type_definition_not_found"),
176            Self::DatatypeInvalidBase => i18n!("msg_datatype_invalid_base"),
177            Self::TypeClassIncompatible => {
178                i18n!("msg_typeclass_incompatible")
179            }
180            Self::PropertyIncompatible => {
181                i18n!("msg_property_incompatible")
182            }
183            Self::RdfDefinitionIncompatible => {
184                i18n!("msg_rdf_definition_incompatible")
185            }
186            Self::FeatureSetNotUnion => i18n!("msg_featureset_not_union"),
187            Self::PropertyReferenceNotProperty => i18n!("msg_property_reference_not_property"),
188            Self::LibraryDefinitionNotAllowed => i18n!("msg_library_definition_not_allowed"),
189            Self::DimensionParentNotEntity => i18n!("msg_dimension_parent_not_entity"),
190            Self::SourceEntityNotEntity => i18n!("msg_source_entity_not_entity"),
191            Self::SourceEntityMissingMember => i18n!("msg_source_entity_missing_member"),
192            Self::DeprecatedTermUsed => i18n!("msg_deprecated_term_used"),
193            Self::DuplicateModuleImport => i18n!("msg_duplicate_module_import"),
194            Self::DuplicateDefinitionImport => i18n!("msg_duplicate_definition_import"),
195            Self::ValidationIncomplete => i18n!("msg_validation_incomplete"),
196            Self::ModuleVersionInfoEmpty => i18n!("msg_module_version_info_empty"),
197            Self::IncompleteModule => i18n!("msg_incomplete_module"),
198            Self::IncompleteDefinition => i18n!("msg_incomplete_definition"),
199            Self::IncompleteMember => i18n!("msg_incomplete_member"),
200            Self::StringWithoutLanguage => i18n!("msg_string_without_language"),
201            Self::UnconstrainedDatatype => i18n!("msg_unconstrained_datatype"),
202            Self::DoubleUnderscoredIdentifier => i18n!("msg_double_underscored_identifier"),
203            Self::IdentifierNotPreferredCase => i18n!("msg_not_preferred_case"),
204        }
205    }
206
207    /// Return a URL (as String) for the associated help documentation.
208    #[inline(always)]
209    pub fn url_string(&self) -> String {
210        format!("https://sdml.io/errors/#{self}")
211    }
212}