diff --git a/README.md b/README.md index 90f1393..fdbfd62 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ an I/O error occurred trying to open /some/path: file not found be logged directly: ```rust +// Using the adapter constructor + // explicit key info!( log, "something happened"; "my-key" => InlineErrorChain::new(&err), @@ -52,6 +54,18 @@ info!( info!( log, "something happened"; InlineErrorChain::new(&err), ); + +// Using the blanket method implementation + +// explicit key +info!( + log, "something happened"; "my-key" => err.as_inline_error_chain(), +); + +// key omitted; will log with the key "error" +info!( + log, "something happened"; err.as_inline_error_chain(), +); ``` With the `derive` feature enabled, error types can `#[derive(SlogInlineError)]` diff --git a/examples/basic.rs b/examples/basic.rs index e258de8..f0c757e 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -6,6 +6,7 @@ use slog::info; use slog::o; use slog::Drain; use slog::Logger; +use slog_error_chain::AsInlineErrorChain; use slog_error_chain::InlineErrorChain; use std::io; use std::path::PathBuf; @@ -37,6 +38,6 @@ fn main() { ); info!( log, "logging error with InlineErrorChain, implicit key"; - InlineErrorChain::new(&err), + err.as_inline_error_chain(), ); } diff --git a/src/lib.rs b/src/lib.rs index 4e0ed0c..4dcd2be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,19 @@ impl fmt::Display for InlineErrorChain<'_> { } } +/// A trait for conveniently constructing [`InlineErrorChain`]s from [`Error`]s. +pub trait AsInlineErrorChain: Error { + /// A convenient wrapper around [`InlineErrorChain::new`]. + fn as_inline_error_chain<'a>(&'a self) -> InlineErrorChain<'a>; +} + +/// Implementation for all [`Error`] types +impl AsInlineErrorChain for E { + fn as_inline_error_chain<'a>(&'a self) -> InlineErrorChain<'a> { + InlineErrorChain::new(self) + } +} + #[cfg(test)] mod tests { use std::io; @@ -108,5 +121,11 @@ mod tests { InlineErrorChain::new(&err).to_string(), "error b: error a: test error" ); + + // Confirm AsInlineErrorChain works as intended + assert_eq!( + err.as_inline_error_chain().to_string(), + "error b: error a: test error" + ); } } diff --git a/src/nested_values.rs b/src/nested_values.rs index c6058bd..4bd9b48 100644 --- a/src/nested_values.rs +++ b/src/nested_values.rs @@ -184,6 +184,19 @@ impl SerdeValue for ArrayErrorChain<'_> { } } +/// A trait for conveniently constructing [`ArrayErrorChain`]s from [`Error`]s. +pub trait AsArrayErrorChain: Error { + /// A convenient wrapper around [`ArrayErrorChain::new`]. + fn as_array_error_chain<'a>(&'a self) -> ArrayErrorChain<'a>; +} + +/// Implementation for all [`Error`] types +impl AsArrayErrorChain for E { + fn as_array_error_chain<'a>(&'a self) -> ArrayErrorChain<'a> { + ArrayErrorChain::new(self) + } +} + #[cfg(test)] mod tests { use super::*; @@ -277,6 +290,9 @@ mod tests { let chain = ArrayErrorChain::new(&err); assert_eq!(chain.to_string(), "test error"); + // Check AsArrayErrorChain implementation + assert_eq!(err.as_array_error_chain().to_string(), "test error"); + let mut out = StringSerializer::default(); chain.serialize_fallback("unused", &mut out).unwrap(); assert_eq!(out.0, "test error");