1#![warn(unused_crate_dependencies)]
9
10pub use indexer::{Indexer, LineIndexer};
11pub use span::{SimpleSpan, Span};
12use std::fmt;
13
14mod indexer;
15mod span;
16
17#[cfg(feature = "annotate-snippets")]
18mod annotate_snippets_impl;
19#[cfg(feature = "ariadne")]
20mod ariadne_impl;
21#[cfg(feature = "codespan-reporting")]
22mod codespan_reporting_impl;
23#[cfg(feature = "miette")]
24mod miette_impl;
25
26#[derive(Clone, Copy, Default)]
28pub enum Kind {
29 #[default]
31 Error,
32 Warn,
34}
35
36impl Kind {
37 pub fn short_str(&self) -> &'static str {
39 match self {
40 Kind::Error => "E",
41 Kind::Warn => "W",
42 }
43 }
44}
45
46pub trait ErrorType: std::error::Error {
51 type Span: Span;
53 type Message: fmt::Display;
55
56 fn kind(&self) -> Kind;
58 fn number(&self) -> &str;
60 fn code(&self) -> &str;
65 fn primary_span(&self) -> Self::Span;
67 fn primary_message(&self) -> Self::Message;
69 fn primary_label(&self) -> Self::Message;
71
72 #[cfg(feature = "annotate-snippets")]
76 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
77 let result = annotate_snippets_impl::fmt_as_annotate_snippets(
78 self,
79 annotate_snippets::display_list::FormatOptions::default(),
80 );
81 Ok(result)
82 }
83 #[cfg(feature = "annotate-snippets")]
88 fn fmt_as_annotate_snippets_with_opts(
89 &self,
90 opts: annotate_snippets::display_list::FormatOptions,
91 ) -> Result<String, std::io::Error> {
92 let result = annotate_snippets_impl::fmt_as_annotate_snippets(self, opts);
93 Ok(result)
94 }
95
96 #[cfg(feature = "ariadne")]
100 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
101 ariadne_impl::fmt_as_ariadne_report(
102 self,
103 ariadne::Config::new().with_index_type(ariadne::IndexType::Byte),
104 )
105 }
106 #[cfg(feature = "ariadne")]
111 fn fmt_as_ariadne_report_with(
112 &self,
113 config: ariadne::Config,
114 ) -> Result<String, std::io::Error> {
115 ariadne_impl::fmt_as_ariadne_report(self, config)
116 }
117 #[cfg(feature = "codespan-reporting")]
122 fn as_codespan_diagnostic(
123 &self,
124 ) -> (
125 codespan_reporting::diagnostic::Diagnostic<usize>,
126 codespan_reporting_impl::Files<Self>,
127 ) {
128 codespan_reporting_impl::to_codespan_diagnostic(self)
129 }
130 #[cfg(feature = "codespan-reporting")]
135 fn fmt_as_codespan_diagnostic_with(
136 &self,
137 config: codespan_reporting::term::Config,
138 styles: Option<&codespan_reporting::term::Styles>,
139 ) -> Result<String, impl std::error::Error> {
140 codespan_reporting_impl::fmt_as_codespan_diagnostic(self, config, styles)
141 }
142
143 #[cfg(feature = "miette")]
147 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
148 where
149 Self::Span: Send + Sync,
150 {
151 miette_impl::Wrapper::new(self)
152 }
153 #[cfg(feature = "miette")]
158 fn fmt_as_miette_diagnostic_with(&self, handler: &impl miette::ReportHandler) -> String
159 where
160 Self: 'static + Sized,
161 Self::Span: Send + Sync,
162 {
163 miette_impl::Wrapper::new(self).fmt_with(handler)
164 }
165}
166
167impl<T: ErrorType + ?Sized> ErrorType for &T {
168 type Span = T::Span;
169 type Message = T::Message;
170
171 fn kind(&self) -> Kind {
172 (*self).kind()
173 }
174 fn number(&self) -> &str {
175 (*self).number()
176 }
177 fn code(&self) -> &str {
178 (*self).code()
179 }
180 fn primary_span(&self) -> Self::Span {
181 (*self).primary_span()
182 }
183 fn primary_message(&self) -> Self::Message {
184 (*self).primary_message()
185 }
186 fn primary_label(&self) -> Self::Message {
187 (*self).primary_label()
188 }
189
190 #[cfg(feature = "annotate-snippets")]
191 fn fmt_as_annotate_snippets(&self) -> Result<String, std::io::Error> {
192 (*self).fmt_as_annotate_snippets()
193 }
194 #[cfg(feature = "annotate-snippets")]
195 fn fmt_as_annotate_snippets_with_opts(
196 &self,
197 opts: annotate_snippets::display_list::FormatOptions,
198 ) -> Result<String, std::io::Error> {
199 (*self).fmt_as_annotate_snippets_with_opts(opts)
200 }
201
202 #[cfg(feature = "ariadne")]
203 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
204 (*self).fmt_as_ariadne_report()
205 }
206 #[cfg(feature = "ariadne")]
207 fn fmt_as_ariadne_report_with(
208 &self,
209 config: ariadne::Config,
210 ) -> Result<String, std::io::Error> {
211 (*self).fmt_as_ariadne_report_with(config)
212 }
213
214 #[cfg(feature = "miette")]
215 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
216 where
217 Self::Span: Send + Sync,
218 {
219 (*self).as_miette_diagnostic()
220 }
221}