-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
switch from using eyre prototype to actual eyre (#1)
- add ci - update docs - set default lints - bump version for new release
- Loading branch information
Showing
4 changed files
with
241 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: {} | ||
|
||
name: Continuous integration | ||
|
||
jobs: | ||
check: | ||
name: Check | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
rust: | ||
- stable | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{ matrix.rust }} | ||
override: true | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: check | ||
|
||
test-features: | ||
name: Test Suite | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: stable | ||
override: true | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
args: --all-features | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
args: --no-default-features | ||
|
||
test-versions: | ||
name: Test Suite | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
rust: | ||
- stable | ||
- beta | ||
- nightly | ||
- 1.39.0 | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{ matrix.rust }} | ||
override: true | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
|
||
test-os: | ||
name: Test Suite | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, windows-latest, macOS-latest] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: stable | ||
override: true | ||
profile: minimal | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
|
||
fmt: | ||
name: Rustfmt | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
rust: | ||
- stable | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{ matrix.rust }} | ||
override: true | ||
- run: rustup component add rustfmt | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: fmt | ||
args: --all -- --check | ||
|
||
clippy: | ||
name: Clippy | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
rust: | ||
- stable | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{ matrix.rust }} | ||
override: true | ||
- run: rustup component add clippy | ||
- uses: actions-rs/cargo@v1 | ||
with: | ||
command: clippy | ||
args: --all-targets --all-features -- -D warnings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,116 @@ | ||
#![feature(backtrace)] | ||
use eyre_impl::{ErrorReporter, Indented}; | ||
use std::backtrace::{Backtrace, BacktraceStatus}; | ||
use std::fmt::{self, Write as _}; | ||
|
||
//! This library provides a custom [`eyre::EyreContext`] type for usage with [`eyre`] that provides | ||
//! a minimal error report with no additional context. Essentially the minimal implementation of an | ||
//! error reporter. | ||
//! | ||
//! # Example | ||
//! | ||
//! ```rust,should_panic | ||
//! use eyre::{eyre, WrapErr}; | ||
//! use simple_eyre::Report; | ||
//! | ||
//! fn main() -> Result<(), Report> { | ||
//! let e: Report = eyre!("oh no this program is just bad!"); | ||
//! | ||
//! Err(e).wrap_err("usage example successfully experienced a failure") | ||
//! } | ||
//! ``` | ||
//! | ||
//! [`eyre::EyreContext`]: https://docs.rs/eyre/*/eyre/trait.EyreContext.html | ||
//! [`eyre`]: https://docs.rs/eyre | ||
#![doc(html_root_url = "https://docs.rs/simple-eyre/0.2.0")] | ||
#![warn( | ||
missing_debug_implementations, | ||
missing_docs, | ||
missing_doc_code_examples, | ||
rust_2018_idioms, | ||
unreachable_pub, | ||
bad_style, | ||
const_err, | ||
dead_code, | ||
improper_ctypes, | ||
non_shorthand_field_patterns, | ||
no_mangle_generic_items, | ||
overflowing_literals, | ||
path_statements, | ||
patterns_in_fns_without_body, | ||
private_in_public, | ||
unconditional_recursion, | ||
unused, | ||
unused_allocation, | ||
unused_comparisons, | ||
unused_parens, | ||
while_true | ||
)] | ||
use eyre::Chain; | ||
use eyre::EyreContext; | ||
use indenter::indented; | ||
use std::error::Error; | ||
|
||
/// A custom context type for minimal error reporting via `eyre` | ||
#[derive(Debug)] | ||
pub struct BoxError(Box<dyn std::error::Error + Send + Sync + 'static>); | ||
|
||
impl std::error::Error for BoxError { | ||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | ||
self.0.source() | ||
} | ||
} | ||
|
||
impl fmt::Display for BoxError { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Display::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
pub struct Context { | ||
backtrace: Backtrace, | ||
} | ||
|
||
impl Default for Context { | ||
fn default() -> Self { | ||
Self { | ||
backtrace: Backtrace::capture(), | ||
} | ||
} | ||
} | ||
|
||
pub struct ErrReport(ErrorReporter<BoxError, Context>); | ||
pub struct Context; | ||
|
||
impl<E> From<E> for ErrReport | ||
where | ||
E: std::error::Error + Send + Sync + 'static, | ||
{ | ||
fn from(err: E) -> Self { | ||
ErrReport(ErrorReporter::from(BoxError(Box::new(err)))) | ||
impl EyreContext for Context { | ||
#[allow(unused_variables)] | ||
fn default(error: &(dyn Error + 'static)) -> Self { | ||
Self | ||
} | ||
} | ||
|
||
impl fmt::Debug for ErrReport { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
let error = &self.0.error; | ||
fn debug( | ||
&self, | ||
error: &(dyn Error + 'static), | ||
f: &mut core::fmt::Formatter<'_>, | ||
) -> core::fmt::Result { | ||
use core::fmt::Write as _; | ||
|
||
if f.alternate() { | ||
return fmt::Debug::fmt(error, f); | ||
} | ||
|
||
let errors = self.0.chain().rev().enumerate(); | ||
|
||
writeln!(f)?; | ||
|
||
for (n, error) in errors { | ||
write!(Indented::numbered(f, n), "{}", error)?; | ||
writeln!(f)?; | ||
} | ||
|
||
let backtrace = &self.0.context.backtrace; | ||
if let BacktraceStatus::Captured = backtrace.status() { | ||
write!(f, "\n\n{}", backtrace)?; | ||
return core::fmt::Debug::fmt(error, f); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl fmt::Display for ErrReport { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}", self.0.error)?; | ||
|
||
if f.alternate() { | ||
for cause in self.0.chain().skip(1) { | ||
write!(f, ": {}", cause)?; | ||
write!(f, "{}", error)?; | ||
|
||
if let Some(cause) = error.source() { | ||
write!(f, "\n\nCaused by:")?; | ||
let multiple = cause.source().is_some(); | ||
for (n, error) in Chain::new(cause).enumerate() { | ||
writeln!(f)?; | ||
if multiple { | ||
write!(indented(f).ind(n), "{}", error)?; | ||
} else { | ||
write!(indented(f), "{}", error)?; | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
/// A type alias for `eyre::Report<simple_eyre::Context>` | ||
/// | ||
/// # Example | ||
/// | ||
/// ```rust | ||
/// use simple_eyre::Report; | ||
/// | ||
/// # struct Config; | ||
/// fn try_thing(path: &str) -> Result<Config, Report> { | ||
/// // ... | ||
/// # Ok(Config) | ||
/// } | ||
/// ``` | ||
pub type Report = eyre::Report<Context>; | ||
|
||
/// A type alias for `Result<T, simple_eyre::Report>` | ||
/// | ||
/// # Example | ||
/// | ||
///``` | ||
/// fn main() -> simple_eyre::Result<()> { | ||
/// | ||
/// // ... | ||
/// | ||
/// Ok(()) | ||
/// } | ||
/// ``` | ||
pub type Result<T, E = Report> = core::result::Result<T, E>; |