1#![warn(unused_crate_dependencies)]
9#![cfg_attr(docsrs, feature(doc_cfg))]
10
11pub use indexer::{Indexer, LineIndexer};
12pub use span::{SimpleSpan, Span};
13use std::fmt;
14
15mod indexer;
16mod span;
17
18#[cfg(feature = "annotate-snippets")]
19mod annotate_snippets_impl;
20#[cfg(feature = "ariadne")]
21mod ariadne_impl;
22#[cfg(feature = "codespan-reporting")]
23mod codespan_reporting_impl;
24#[cfg(feature = "miette")]
25mod miette_impl;
26
27#[derive(Clone, Copy, Default)]
29pub enum Kind {
30 #[default]
32 Error,
33 Warn,
35}
36
37impl Kind {
38 pub fn short_str(&self) -> &'static str {
40 match self {
41 Kind::Error => "E",
42 Kind::Warn => "W",
43 }
44 }
45}
46
47pub trait ErrorType: std::error::Error {
52 type Span: Span;
54 type Message: fmt::Display;
56
57 fn kind(&self) -> Kind;
59 fn number(&self) -> &str;
61 fn code(&self) -> &str;
66 fn primary_span(&self) -> Self::Span;
68 fn primary_message(&self) -> Self::Message;
70 fn primary_label(&self) -> Self::Message;
72
73 #[cfg(feature = "annotate-snippets")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
78 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
79 let result = annotate_snippets_impl::fmt_as_annotate_snippets(
80 self,
81 annotate_snippets::display_list::FormatOptions::default(),
82 );
83 Ok(result)
84 }
85 #[cfg(feature = "annotate-snippets")]
90 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
91 fn fmt_as_annotate_snippets_with_opts(
92 &self,
93 opts: annotate_snippets::display_list::FormatOptions,
94 ) -> Result<String, std::io::Error> {
95 let result = annotate_snippets_impl::fmt_as_annotate_snippets(self, opts);
96 Ok(result)
97 }
98
99 #[cfg(feature = "ariadne")]
103 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
104 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
105 ariadne_impl::fmt_as_ariadne_report(
106 self,
107 ariadne::Config::new().with_index_type(ariadne::IndexType::Byte),
108 )
109 }
110 #[cfg(feature = "ariadne")]
115 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
116 fn fmt_as_ariadne_report_with(
117 &self,
118 config: ariadne::Config,
119 ) -> Result<String, std::io::Error> {
120 ariadne_impl::fmt_as_ariadne_report(self, config)
121 }
122
123 #[cfg(feature = "codespan-reporting")]
128 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
129 fn as_codespan_diagnostic(
130 &self,
131 ) -> (
132 codespan_reporting::diagnostic::Diagnostic<usize>,
133 codespan_reporting_impl::Files<Self>,
134 ) {
135 codespan_reporting_impl::to_codespan_diagnostic(self)
136 }
137 #[cfg(feature = "codespan-reporting")]
142 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
143 fn fmt_as_codespan_diagnostic_with(
144 &self,
145 config: codespan_reporting::term::Config,
146 styles: Option<&codespan_reporting::term::Styles>,
147 ) -> Result<String, codespan_reporting::files::Error> {
148 codespan_reporting_impl::fmt_as_codespan_diagnostic(self, config, styles)
149 }
150
151 #[cfg(feature = "miette")]
155 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
156 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
157 where
158 Self::Span: Send + Sync,
159 {
160 miette_impl::Wrapper::new(self)
161 }
162 #[cfg(feature = "miette")]
167 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
168 fn fmt_as_miette_diagnostic_with(&self, handler: &impl miette::ReportHandler) -> String
169 where
170 Self: 'static + Sized,
171 Self::Span: Send + Sync,
172 {
173 miette_impl::Wrapper::new(self).fmt_with(handler)
174 }
175}
176
177impl<T: ErrorType + ?Sized> ErrorType for &T {
178 type Span = T::Span;
179 type Message = T::Message;
180
181 #[inline]
182 fn kind(&self) -> Kind {
183 (*self).kind()
184 }
185 #[inline]
186 fn number(&self) -> &str {
187 (*self).number()
188 }
189 #[inline]
190 fn code(&self) -> &str {
191 (*self).code()
192 }
193 #[inline]
194 fn primary_span(&self) -> Self::Span {
195 (*self).primary_span()
196 }
197 #[inline]
198 fn primary_message(&self) -> Self::Message {
199 (*self).primary_message()
200 }
201 #[inline]
202 fn primary_label(&self) -> Self::Message {
203 (*self).primary_label()
204 }
205
206 #[cfg(feature = "annotate-snippets")]
207 #[inline]
208 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
209 (*self).fmt_as_annotate_snippets()
210 }
211 #[cfg(feature = "annotate-snippets")]
212 #[inline]
213 fn fmt_as_annotate_snippets_with_opts(
214 &self,
215 opts: annotate_snippets::display_list::FormatOptions,
216 ) -> Result<String, std::io::Error> {
217 (*self).fmt_as_annotate_snippets_with_opts(opts)
218 }
219
220 #[cfg(feature = "ariadne")]
221 #[inline]
222 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
223 (*self).fmt_as_ariadne_report()
224 }
225 #[cfg(feature = "ariadne")]
226 #[inline]
227 fn fmt_as_ariadne_report_with(
228 &self,
229 config: ariadne::Config,
230 ) -> Result<String, std::io::Error> {
231 (*self).fmt_as_ariadne_report_with(config)
232 }
233
234 #[cfg(feature = "codespan-reporting")]
235 #[inline]
236 fn as_codespan_diagnostic(
237 &self,
238 ) -> (
239 codespan_reporting::diagnostic::Diagnostic<usize>,
240 codespan_reporting_impl::Files<Self>,
241 ) {
242 (*self).as_codespan_diagnostic()
243 }
244 #[cfg(feature = "codespan-reporting")]
245 #[inline]
246 fn fmt_as_codespan_diagnostic_with(
247 &self,
248 config: codespan_reporting::term::Config,
249 styles: Option<&codespan_reporting::term::Styles>,
250 ) -> Result<String, codespan_reporting::files::Error> {
251 (*self).fmt_as_codespan_diagnostic_with(config, styles)
252 }
253
254 #[cfg(feature = "miette")]
255 #[inline]
256 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
257 where
258 Self::Span: Send + Sync,
259 {
260 (*self).as_miette_diagnostic()
261 }
262}