Types to track error codes and details.
This library provies a [SourceError
] struct that holds:
ErrorCode
]: Enum whose variants indicate error code, simple description.ErrorDetail
]: Enum with matching variants to ErrorCode
, but each variant contains information specific to an instance of the error.Severity
]: The severity to report the error.This library backs onto [codespan-reporting
] to render diagnostic errors.
The "codespan"
feature can also be used to expose [codespan
] types:
toml
srcerr = { version = "0.3.0", features = ["codespan"] }
1. Implement ErrorCode
```rust
pub enum SimpleErrorCode { /// Error when a value is out of range. ValueOutOfRange, /// Error when a string is too long. StringTooLong, }
impl ErrorCode for SimpleErrorCode { const ERRORCODEMAX: usize = 2; const PREFIX: &'static str = "E";
fn code(self) -> usize {
match self {
Self::ValueOutOfRange => 1,
Self::StringTooLong => 2,
}
}
fn description(self) -> &'static str {
match self {
Self::ValueOutOfRange => "Value out of range.",
Self::StringTooLong => "String provided is too long.",
}
}
} ```
2. Implement ErrorDetail
```rust
pub enum SimpleErrorDetail {
/// Error when a value is out of range.
ValueOutOfRange {
/// ID of the file containing the invalid value.
fileid: usize,
/// The value.
value: i32,
/// Byte begin and end indices where the value is defined.
valuebyteindices: Range
impl<'files> ErrorDetail<'files> for SimpleErrorDetail { type Files = SimpleFiles<&'files str, &'files str>;
fn labels(&self) -> Vec<Label<usize>> {
match self {
Self::ValueOutOfRange {
file_id,
value_byte_indices,
range,
..
} => {
vec![
Label::primary(*file_id, value_byte_indices.clone()).with_message(format!(
"not within the range: `{}..={}`",
range.start(),
range.end()
)),
]
}
Self::StringTooLong {
file_id,
value_byte_indices,
limit,
..
} => {
vec![
Label::primary(*file_id, value_byte_indices.clone())
.with_message(format!("exceeds the {} character limit.", limit)),
]
}
}
}
fn notes(&self, _files: &Self::Files) -> Vec<String> {
match self {
Self::ValueOutOfRange { range, .. } => {
let valid_exprs = range.clone().map(|n| Cow::Owned(n.to_string()));
let suggestion = Note::valid_exprs(valid_exprs).expect("Failed to format note.");
vec![suggestion]
}
Self::StringTooLong { .. } => vec![],
}
}
} ```
3. Construct SourceError when there is an error.
```rust fn valueoutofrange<'f>( fileid: usize, ) -> SourceError<'f, SimpleErrorCode, SimpleErrorDetail, SimpleFiles<&'f str, &'f str>> { let errorcode = SimpleErrorCode::ValueOutOfRange; let errordetail = SimpleErrorDetail::ValueOutOfRange { fileid, value: -1, valuebyte_indices: 21..23, range: 1..=3, }; let severity = Severity::Error;
SourceError::new(error_code, error_detail, severity)
}
fn stringtoolong<'f>( fileid: usize, content: &str, ) -> SourceError<'f, SimpleErrorCode, SimpleErrorDetail, SimpleFiles<&'f str, &'f str>> { let errorcode = SimpleErrorCode::StringTooLong; let errordetail = SimpleErrorDetail::StringTooLong { fileid, value: content[40..47].tostring(), valuebyte_indices: 39..48, limit: 5, }; let severity = Severity::Error;
SourceError::new(error_code, error_detail, severity)
} ```
4. Output the diagnostic message.
```rust let valueoutofrange = valueoutofrange(fileid); let valueoutofrange = valueoutofrange.asdiagnostic(&files); let stringtoolong = stringtoolong(fileid, content); let stringtoolong = stringtoolong.asdiagnostic(&files);
let writer = StandardStream::stderr(ColorChoice::Always); let config = term::Config::default(); term::emit(&mut writer.lock(), &config, &files, &valueoutofrange)?; term::emit(&mut writer.lock(), &config, &files, &stringtoo_long)?; ```
Sample usage can be seen in the examples.
cargo run --example simple
cargo run --example source_ref_hint
cargo run --example long_expr_context
cargo run --example html > /tmp/index.html
cargo run --example codespan --features codespan
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.