1pub use indexer::{Indexer, LineIndexer};
10pub use span::{SimpleSpan, Span};
11use std::fmt;
12
13mod indexer;
14mod span;
15
16#[cfg(feature = "annotate-snippets")]
17mod annotate_snippets_impl;
18#[cfg(feature = "ariadne")]
19mod ariadne_impl;
20#[cfg(feature = "codespan-reporting")]
21mod codespan_reporting_impl;
22#[cfg(feature = "miette")]
23mod miette_impl;
24
25#[derive(Clone, Copy, Default)]
27pub enum Kind {
28 #[default]
30 Error,
31 Warn,
33}
34
35impl Kind {
36 pub fn short_str(&self) -> &'static str {
38 match self {
39 Kind::Error => "E",
40 Kind::Warn => "W",
41 }
42 }
43}
44
45pub trait ErrorEnum: std::error::Error {
47 type Span: Span;
49 type Message: fmt::Display;
51
52 fn kind(&self) -> Kind;
54 fn number(&self) -> &str;
56 fn code(&self) -> &str;
61 fn primary_span(&self) -> Self::Span;
63 fn primary_message(&self) -> Self::Message;
65 fn primary_label(&self) -> Self::Message;
67
68 #[cfg(feature = "annotate-snippets")]
72 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
73 let result = annotate_snippets_impl::fmt_as_annotate_snippets(
74 self,
75 annotate_snippets::display_list::FormatOptions::default(),
76 );
77 Ok(result)
78 }
79 #[cfg(feature = "annotate-snippets")]
84 fn fmt_as_annotate_snippets_with_opts(
85 &self,
86 opts: annotate_snippets::display_list::FormatOptions,
87 ) -> Result<String, std::io::Error> {
88 let result = annotate_snippets_impl::fmt_as_annotate_snippets(self, opts);
89 Ok(result)
90 }
91
92 #[cfg(feature = "ariadne")]
96 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
97 ariadne_impl::fmt_as_ariadne_report(
98 self,
99 ariadne::Config::new().with_index_type(ariadne::IndexType::Byte),
100 )
101 }
102 #[cfg(feature = "ariadne")]
107 fn fmt_as_ariadne_report_with(
108 &self,
109 config: ariadne::Config,
110 ) -> Result<String, std::io::Error> {
111 ariadne_impl::fmt_as_ariadne_report(self, config)
112 }
113 #[cfg(feature = "codespan-reporting")]
118 fn as_codespan_diagnostic(
119 &self,
120 ) -> (
121 codespan_reporting::diagnostic::Diagnostic<usize>,
122 codespan_reporting_impl::Files<Self>,
123 ) {
124 codespan_reporting_impl::to_codespan_diagnostic(self)
125 }
126 #[cfg(feature = "codespan-reporting")]
131 fn fmt_as_codespan_diagnostic_with(
132 &self,
133 config: codespan_reporting::term::Config,
134 styles: Option<&codespan_reporting::term::Styles>,
135 ) -> Result<String, impl std::error::Error> {
136 codespan_reporting_impl::fmt_as_codespan_diagnostic(self, config, styles)
137 }
138
139 #[cfg(feature = "miette")]
143 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
144 where
145 Self::Span: Send + Sync,
146 {
147 miette_impl::Wrapper::new(self)
148 }
149 #[cfg(feature = "miette")]
154 fn fmt_as_miette_diagnostic_with(&self, handler: &impl miette::ReportHandler) -> String
155 where
156 Self: 'static + Sized,
157 Self::Span: Send + Sync,
158 {
159 miette_impl::Wrapper::new(self).fmt_with(handler)
160 }
161}
162
163impl<T: ErrorEnum + ?Sized> ErrorEnum for &T {
164 type Span = T::Span;
165 type Message = T::Message;
166
167 fn kind(&self) -> Kind {
168 (*self).kind()
169 }
170 fn number(&self) -> &str {
171 (*self).number()
172 }
173 fn code(&self) -> &str {
174 (*self).code()
175 }
176 fn primary_span(&self) -> Self::Span {
177 (*self).primary_span()
178 }
179 fn primary_message(&self) -> Self::Message {
180 (*self).primary_message()
181 }
182 fn primary_label(&self) -> Self::Message {
183 (*self).primary_label()
184 }
185
186 #[cfg(feature = "annotate-snippets")]
187 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
188 (*self).fmt_as_annotate_snippets()
189 }
190 #[cfg(feature = "annotate-snippets")]
191 fn fmt_as_annotate_snippets_with_opts(
192 &self,
193 opts: annotate_snippets::display_list::FormatOptions,
194 ) -> Result<String, std::io::Error> {
195 (*self).fmt_as_annotate_snippets_with_opts(opts)
196 }
197
198 #[cfg(feature = "ariadne")]
199 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
200 (*self).fmt_as_ariadne_report()
201 }
202 #[cfg(feature = "ariadne")]
203 fn fmt_as_ariadne_report_with(
204 &self,
205 config: ariadne::Config,
206 ) -> Result<String, std::io::Error> {
207 (*self).fmt_as_ariadne_report_with(config)
208 }
209
210 #[cfg(feature = "miette")]
211 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
212 where
213 Self::Span: Send + Sync,
214 {
215 (*self).as_miette_diagnostic()
216 }
217}