From a8cb8fa3407f3a39ee47ad99cb2a41aee2170a8c Mon Sep 17 00:00:00 2001 From: Brooks J Rady Date: Tue, 23 Apr 2024 16:36:56 -0700 Subject: [PATCH] feat!(blanket_impls): impl `Diagnostic` for &T and Box Brings things in line with best practices as described in "Rust for Rustaceans" when it comes to "Ergonomic Trait Implementations" in Chapter 3. Practically means that people can pass more types to any functions taking either `dyn Diagnostic` or `impl Diagnostic`. BREAKING CHANGE: Added blanket impls may overlap with manual user impls. If these impls are just hacks to achieve the same as the blanket ones do, then they can simply be removed. If the impls for `T` and `&T` differ semantically, then the user would need to employ the newtype pattern to avoid overlap. --- src/protocol.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/test_blanket.rs | 13 +++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/test_blanket.rs diff --git a/src/protocol.rs b/src/protocol.rs index 589cd0b..2f1c1b1 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -69,6 +69,48 @@ pub trait Diagnostic: std::error::Error { } } +macro_rules! blanket_ref_impls { + ($($ref_type:ty),+ $(,)?) => { + $( + impl Diagnostic for $ref_type { + fn code<'a>(&'a self) -> Option> { + (**self).code() + } + + fn severity(&self) -> Option { + (**self).severity() + } + + fn help<'a>(&'a self) -> Option> { + (**self).help() + } + + fn url<'a>(&'a self) -> Option> { + (**self).url() + } + + fn source_code(&self) -> Option<&dyn SourceCode> { + (**self).source_code() + } + + fn labels(&self) -> Option + '_>> { + (**self).labels() + } + + fn related<'a>(&'a self) -> Option + 'a>> { + (**self).related() + } + + fn diagnostic_source(&self) -> Option<&dyn Diagnostic> { + (**self).diagnostic_source() + } + } + )+ + }; +} + +blanket_ref_impls!(&T, Box); + macro_rules! box_error_impls { ($($box_type:ty),*) => { $( diff --git a/tests/test_blanket.rs b/tests/test_blanket.rs new file mode 100644 index 0000000..58271ca --- /dev/null +++ b/tests/test_blanket.rs @@ -0,0 +1,13 @@ +use miette::{Diagnostic, MietteDiagnostic}; + +fn assert_diagnostic() {} + +#[test] +fn test_ref() { + assert_diagnostic::<&MietteDiagnostic>() +} + +#[test] +fn test_box() { + assert_diagnostic::>() +}