1#![warn(unused_crate_dependencies)]
9#![no_std]
10#![cfg_attr(docsrs, feature(doc_cfg))]
11
12pub use alloc::{format, string::String};
13use core::fmt;
14pub use indexer::{Indexer, LineIndexer};
15pub use span::{SimpleSpan, Span};
16
17extern crate alloc;
18#[cfg(feature = "std")]
19extern crate std;
20
21mod indexer;
22mod span;
23
24#[cfg(feature = "annotate-snippets")]
25mod annotate_snippets_impl;
26#[cfg(feature = "ariadne")]
27mod ariadne_impl;
28#[cfg(feature = "codespan-reporting")]
29mod codespan_reporting_impl;
30#[cfg(feature = "miette")]
31mod miette_impl;
32
33#[derive(Clone, Copy, Default)]
35pub enum Kind {
36 #[default]
38 Error,
39 Warn,
41}
42
43impl Kind {
44 pub fn short_str(&self) -> &'static str {
46 match self {
47 Kind::Error => "E",
48 Kind::Warn => "W",
49 }
50 }
51}
52
53pub trait ErrorType: core::error::Error {
58 type Span: Span + Default;
60 type Message: fmt::Display;
62
63 fn kind(&self) -> Kind;
65 fn number(&self) -> &str;
67 fn code(&self) -> &str;
72 fn primary_span(&self) -> Option<Self::Span>;
74 fn primary_message(&self) -> Self::Message;
76 fn primary_label(&self) -> Self::Message;
78
79 fn primary(&self) -> (Option<Self::Span>, Self::Message, Self::Message) {
81 (
82 self.primary_span(),
83 self.primary_message(),
84 self.primary_label(),
85 )
86 }
87
88 fn additional(
90 &self,
91 ) -> impl Iterator<Item = (Option<Self::Span>, Self::Message, Self::Message)> + '_;
92
93 #[cfg(feature = "annotate-snippets")]
97 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
98 fn fmt_as_annotate_snippets(&self) -> String {
99 annotate_snippets_impl::fmt_as_annotate_snippets(
100 self,
101 annotate_snippets::display_list::FormatOptions::default(),
102 )
103 }
104 #[cfg(feature = "annotate-snippets")]
109 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
110 fn fmt_as_annotate_snippets_with_opts(
111 &self,
112 opts: annotate_snippets::display_list::FormatOptions,
113 ) -> String {
114 annotate_snippets_impl::fmt_as_annotate_snippets(self, opts)
115 }
116
117 #[cfg(feature = "ariadne")]
121 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
122 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
123 ariadne_impl::fmt_as_ariadne_report(
124 self,
125 ariadne::Config::new().with_index_type(ariadne::IndexType::Byte),
126 )
127 }
128 #[cfg(feature = "ariadne")]
133 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
134 fn fmt_as_ariadne_report_with(
135 &self,
136 config: ariadne::Config,
137 ) -> Result<String, std::io::Error> {
138 ariadne_impl::fmt_as_ariadne_report(self, config)
139 }
140
141 #[cfg(feature = "codespan-reporting")]
146 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
147 fn as_codespan_diagnostic(
148 &self,
149 ) -> (
150 codespan_reporting::diagnostic::Diagnostic<usize>,
151 codespan_reporting_impl::Files<Self>,
152 ) {
153 codespan_reporting_impl::to_codespan_diagnostic(self)
154 }
155 #[cfg(feature = "codespan-reporting")]
160 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
161 fn fmt_as_codespan_diagnostic_with(
162 &self,
163 config: codespan_reporting::term::Config,
164 styles: Option<&codespan_reporting::term::Styles>,
165 ) -> Result<String, codespan_reporting::files::Error> {
166 codespan_reporting_impl::fmt_as_codespan_diagnostic(self, config, styles)
167 }
168
169 #[cfg(feature = "miette")]
173 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
174 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
175 where
176 Self::Span: Send + Sync,
177 {
178 miette_impl::Wrapper::new(self)
179 }
180 #[cfg(feature = "miette")]
185 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
186 fn fmt_as_miette_diagnostic_with(&self, handler: &impl miette::ReportHandler) -> String
187 where
188 Self: 'static + Sized,
189 Self::Span: Send + Sync,
190 {
191 miette_impl::Wrapper::new(self).fmt_with(handler)
192 }
193}
194
195impl<T: ErrorType + ?Sized> ErrorType for &T {
196 type Span = T::Span;
197 type Message = T::Message;
198
199 #[inline]
200 fn kind(&self) -> Kind {
201 (*self).kind()
202 }
203 #[inline]
204 fn number(&self) -> &str {
205 (*self).number()
206 }
207 #[inline]
208 fn code(&self) -> &str {
209 (*self).code()
210 }
211 #[inline]
212 fn primary_span(&self) -> Option<Self::Span> {
213 (*self).primary_span()
214 }
215 #[inline]
216 fn primary_message(&self) -> Self::Message {
217 (*self).primary_message()
218 }
219 #[inline]
220 fn primary_label(&self) -> Self::Message {
221 (*self).primary_label()
222 }
223
224 #[inline]
225 fn primary(&self) -> (Option<Self::Span>, Self::Message, Self::Message) {
226 (*self).primary()
227 }
228
229 #[inline]
230 fn additional(
231 &self,
232 ) -> impl Iterator<Item = (Option<Self::Span>, Self::Message, Self::Message)> + '_ {
233 (*self).additional()
234 }
235
236 #[cfg(feature = "annotate-snippets")]
237 #[inline]
238 fn fmt_as_annotate_snippets(&self) -> String {
239 (*self).fmt_as_annotate_snippets()
240 }
241 #[cfg(feature = "annotate-snippets")]
242 #[inline]
243 fn fmt_as_annotate_snippets_with_opts(
244 &self,
245 opts: annotate_snippets::display_list::FormatOptions,
246 ) -> String {
247 (*self).fmt_as_annotate_snippets_with_opts(opts)
248 }
249
250 #[cfg(feature = "ariadne")]
251 #[inline]
252 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
253 (*self).fmt_as_ariadne_report()
254 }
255 #[cfg(feature = "ariadne")]
256 #[inline]
257 fn fmt_as_ariadne_report_with(
258 &self,
259 config: ariadne::Config,
260 ) -> Result<String, std::io::Error> {
261 (*self).fmt_as_ariadne_report_with(config)
262 }
263
264 #[cfg(feature = "codespan-reporting")]
265 #[inline]
266 fn as_codespan_diagnostic(
267 &self,
268 ) -> (
269 codespan_reporting::diagnostic::Diagnostic<usize>,
270 codespan_reporting_impl::Files<Self>,
271 ) {
272 (*self).as_codespan_diagnostic()
273 }
274 #[cfg(feature = "codespan-reporting")]
275 #[inline]
276 fn fmt_as_codespan_diagnostic_with(
277 &self,
278 config: codespan_reporting::term::Config,
279 styles: Option<&codespan_reporting::term::Styles>,
280 ) -> Result<String, codespan_reporting::files::Error> {
281 (*self).fmt_as_codespan_diagnostic_with(config, styles)
282 }
283
284 #[cfg(feature = "miette")]
285 #[inline]
286 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
287 where
288 Self::Span: Send + Sync,
289 {
290 (*self).as_miette_diagnostic()
291 }
292}