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