1#![warn(unused_crate_dependencies)]
9#![no_std]
10#![cfg_attr(docsrs, feature(doc_cfg))]
11
12pub use alloc::{boxed::Box, 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 {
60 type Span: Span + Default;
62 type Message: fmt::Display;
64
65 fn kind(&self) -> Kind;
67 fn number(&self) -> &str;
69 fn code(&self) -> &str;
74 fn primary_span(&self) -> Option<Self::Span>;
76 fn primary_message(&self) -> Self::Message;
78 fn primary_label(&self) -> Self::Message;
80
81 fn primary(&self) -> (Option<Self::Span>, Self::Message, Self::Message) {
83 (
84 self.primary_span(),
85 self.primary_message(),
86 self.primary_label(),
87 )
88 }
89
90 fn additional(
92 &self,
93 ) -> Box<dyn Iterator<Item = (Option<Self::Span>, Self::Message, Self::Message)>>;
94}
95
96impl<T: ErrorType + ?Sized> ErrorType for &T {
97 type Span = T::Span;
98 type Message = T::Message;
99
100 #[inline]
101 fn kind(&self) -> Kind {
102 (*self).kind()
103 }
104 #[inline]
105 fn number(&self) -> &str {
106 (*self).number()
107 }
108 #[inline]
109 fn code(&self) -> &str {
110 (*self).code()
111 }
112 #[inline]
113 fn primary_span(&self) -> Option<Self::Span> {
114 (*self).primary_span()
115 }
116 #[inline]
117 fn primary_message(&self) -> Self::Message {
118 (*self).primary_message()
119 }
120 #[inline]
121 fn primary_label(&self) -> Self::Message {
122 (*self).primary_label()
123 }
124
125 #[inline]
126 fn primary(&self) -> (Option<Self::Span>, Self::Message, Self::Message) {
127 (*self).primary()
128 }
129
130 #[inline]
131 fn additional(
132 &self,
133 ) -> Box<dyn Iterator<Item = (Option<Self::Span>, Self::Message, Self::Message)>> {
134 (*self).additional()
135 }
136}
137
138pub trait ErrorTypeExt: ErrorType {
140 #[cfg(feature = "annotate-snippets")]
144 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
145 fn fmt_as_annotate_snippets(&self) -> String {
146 annotate_snippets_impl::fmt_as_annotate_snippets(
147 self,
148 annotate_snippets::display_list::FormatOptions::default(),
149 )
150 }
151 #[cfg(feature = "annotate-snippets")]
156 #[cfg_attr(docsrs, doc(cfg(feature = "annotate-snippets")))]
157 fn fmt_as_annotate_snippets_with_opts(
158 &self,
159 opts: annotate_snippets::display_list::FormatOptions,
160 ) -> String {
161 annotate_snippets_impl::fmt_as_annotate_snippets(self, opts)
162 }
163
164 #[cfg(feature = "ariadne")]
168 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
169 fn fmt_as_ariadne_report(&self) -> Result<String, std::io::Error> {
170 ariadne_impl::fmt_as_ariadne_report(
171 self,
172 ariadne::Config::new().with_index_type(ariadne::IndexType::Byte),
173 )
174 }
175 #[cfg(feature = "ariadne")]
180 #[cfg_attr(docsrs, doc(cfg(feature = "ariadne")))]
181 fn fmt_as_ariadne_report_with(
182 &self,
183 config: ariadne::Config,
184 ) -> Result<String, std::io::Error> {
185 ariadne_impl::fmt_as_ariadne_report(self, config)
186 }
187
188 #[cfg(feature = "codespan-reporting")]
193 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
194 fn as_codespan_diagnostic(
195 &self,
196 ) -> (
197 codespan_reporting::diagnostic::Diagnostic<usize>,
198 codespan_reporting_impl::Files<Self>,
199 ) {
200 codespan_reporting_impl::to_codespan_diagnostic(self)
201 }
202 #[cfg(feature = "codespan-reporting")]
207 #[cfg_attr(docsrs, doc(cfg(feature = "codespan-reporting")))]
208 fn fmt_as_codespan_diagnostic_with(
209 &self,
210 config: codespan_reporting::term::Config,
211 styles: Option<&codespan_reporting::term::Styles>,
212 ) -> Result<String, codespan_reporting::files::Error> {
213 codespan_reporting_impl::fmt_as_codespan_diagnostic(self, config, styles)
214 }
215
216 #[cfg(feature = "miette")]
220 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
221 fn as_miette_diagnostic(&self) -> impl miette::Diagnostic + '_
222 where
223 Self::Span: Send + Sync,
224 {
225 miette_impl::Wrapper::new(self)
226 }
227 #[cfg(feature = "miette")]
232 #[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
233 fn fmt_as_miette_diagnostic_with(&self, handler: &impl miette::ReportHandler) -> String
234 where
235 Self: 'static + Sized,
236 Self::Span: Send + Sync,
237 {
238 miette_impl::Wrapper::new(self).fmt_with(handler)
239 }
240}
241
242impl<T: ErrorType + ?Sized> ErrorTypeExt for T {}