mirror of https://github.com/zkat/miette.git
fix: address review comments
- Fixed compilation errors in no-std mode (TestError Debug derive, ToString imports) - Addressed consistency issues: Option qualification, StdError naming, Borrow impl - Fixed feature flag logic for supports_color function with proper priority ordering - Added conditional compilation for std-dependent features in panic.rs, handler.rs, theme.rs - Made syntect-highlighter feature explicitly require std - Consolidated duplicate Borrow implementations using core::borrow::Borrow
This commit is contained in:
parent
18c217f0dc
commit
359941fdef
|
|
@ -65,7 +65,7 @@ fancy-no-backtrace = [
|
|||
"dep:supports-unicode",
|
||||
]
|
||||
fancy = ["fancy-no-backtrace", "dep:backtrace", "dep:backtrace-ext"]
|
||||
syntect-highlighter = ["fancy-no-backtrace", "dep:syntect"]
|
||||
syntect-highlighter = ["fancy-no-backtrace", "dep:syntect", "std"]
|
||||
|
||||
[workspace]
|
||||
members = ["miette-derive"]
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -58,8 +58,8 @@ diagnostic error code: ruget::api::bad_json
|
|||
|
||||
### Features
|
||||
|
||||
- Generic [`Diagnostic`] protocol, compatible (and dependent on)
|
||||
[`std::error::Error`].
|
||||
- Generic [`Diagnostic`] protocol, compatible with `std::error::Error`.
|
||||
Works without the standard library: Just turn off the default `std` feature and you can use `miette` in places like embedded systems or web browsers that don't have the full standard library. You still need `alloc` for memory management.
|
||||
- Unique error codes on every [`Diagnostic`].
|
||||
- Custom links to get more details on error codes.
|
||||
- Super handy derive macro for defining diagnostic metadata.
|
||||
|
|
@ -93,6 +93,19 @@ If you want to use the fancy printer in all these screenshots:
|
|||
$ cargo add miette --features fancy
|
||||
```
|
||||
|
||||
For computers without the standard library (like microcontrollers or web browsers):
|
||||
|
||||
```sh
|
||||
$ cargo add miette --no-default-features --features derive
|
||||
```
|
||||
|
||||
Available features you can turn on or off:
|
||||
- `std` (on by default): Use the standard library
|
||||
- `derive`: Lets you automatically create error types
|
||||
- `fancy`: Shows pretty error messages with colors
|
||||
- `fancy-no-syscall`: Pretty errors without using system calls
|
||||
- `fancy-no-backtrace`: Pretty errors without showing the call stack
|
||||
|
||||
### Example
|
||||
|
||||
```rust
|
||||
|
|
|
|||
8
build.rs
8
build.rs
|
|
@ -5,12 +5,8 @@ fn main() {
|
|||
println!("cargo:rustc-cfg=nightly")
|
||||
}
|
||||
|
||||
// Configure track_caller based on Rust version
|
||||
if let Ok(version) = rustc_version::version() {
|
||||
if version >= rustc_version::Version::new(1, 46, 0) {
|
||||
println!("cargo:rustc-cfg=track_caller");
|
||||
}
|
||||
}
|
||||
// track_caller is stable since Rust 1.46 (2020), so no version check needed
|
||||
println!("cargo:rustc-cfg=track_caller");
|
||||
|
||||
// Add check-cfg for conditional configurations
|
||||
println!("cargo:rustc-check-cfg=cfg(doc_cfg)");
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ impl Code {
|
|||
let code = &code.as_ref()?.0;
|
||||
Some(match fields {
|
||||
syn::Fields::Named(_) => {
|
||||
quote! { Self::#ident { .. } => Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
quote! { Self::#ident { .. } => core::option::Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
}
|
||||
syn::Fields::Unnamed(_) => {
|
||||
quote! { Self::#ident(..) => Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
quote! { Self::#ident(..) => core::option::Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
}
|
||||
syn::Fields::Unit => {
|
||||
quote! { Self::#ident => Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
quote! { Self::#ident => core::option::Option::Some(alloc::boxed::Box::new(#code)), }
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -72,8 +72,8 @@ impl Code {
|
|||
pub(crate) fn gen_struct(&self) -> Option<TokenStream> {
|
||||
let code = &self.0;
|
||||
Some(quote! {
|
||||
fn code(&self) -> Option<alloc::boxed::Box<dyn core::fmt::Display + '_>> {
|
||||
Some(alloc::boxed::Box::new(#code))
|
||||
fn code(&self) -> core::option::Option<alloc::boxed::Box<dyn core::fmt::Display + '_>> {
|
||||
core::option::Option::Some(alloc::boxed::Box::new(#code))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ impl DiagnosticSource {
|
|||
};
|
||||
quote! {
|
||||
Self::#ident #display_pat => {
|
||||
Some(alloc::borrow::Borrow::borrow(#rel))
|
||||
core::option::Option::Some(alloc::borrow::Borrow::borrow(#rel))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -70,8 +70,8 @@ impl DiagnosticSource {
|
|||
pub(crate) fn gen_struct(&self) -> Option<TokenStream> {
|
||||
let rel = &self.0;
|
||||
Some(quote! {
|
||||
fn diagnostic_source<'a>(&'a self) -> Option<&'a dyn miette::Diagnostic> {
|
||||
Some(alloc::borrow::Borrow::borrow(&self.#rel))
|
||||
fn diagnostic_source<'a>(&'a self) -> core::option::Option<&'a dyn miette::Diagnostic> {
|
||||
core::option::Option::Some(alloc::borrow::Borrow::borrow(&self.#rel))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ impl Diagnostic for MietteError {
|
|||
pub(crate) mod tests {
|
||||
#[cfg(not(feature = "std"))]
|
||||
use crate::StdError as Error;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::string::ToString;
|
||||
#[cfg(feature = "std")]
|
||||
use std::string::ToString;
|
||||
|
||||
use super::*;
|
||||
|
|
@ -101,6 +104,7 @@ pub(crate) mod tests {
|
|||
#[cfg(feature = "std")]
|
||||
pub(crate) struct TestError(pub(crate) io::Error);
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TestError(pub(crate) &'static str);
|
||||
|
||||
impl Display for TestError {
|
||||
|
|
|
|||
|
|
@ -817,14 +817,6 @@ impl AsRef<dyn StdError> for Report {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::borrow::Borrow<dyn Diagnostic> for Report {
|
||||
fn borrow(&self) -> &(dyn Diagnostic + 'static) {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl core::borrow::Borrow<dyn Diagnostic> for Report {
|
||||
fn borrow(&self) -> &(dyn Diagnostic + 'static) {
|
||||
self.as_ref()
|
||||
|
|
|
|||
|
|
@ -60,13 +60,12 @@ impl<T, E: Error + Send + Sync + 'static> IntoDiagnostic<T, E> for Result<T, E>
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::IntoDiagnostic;
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::{self};
|
||||
#[cfg(feature = "std")]
|
||||
use std::string::ToString;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::error::tests::TestError;
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ impl MietteHandlerOpts {
|
|||
// In no-std environment, assume graphics are available
|
||||
true
|
||||
}
|
||||
#[cfg(not(feature = "fancy-no-syscall"))]
|
||||
#[cfg(all(not(feature = "fancy-no-syscall"), feature = "std"))]
|
||||
{
|
||||
// In std environment, check NO_GRAPHICS env var
|
||||
if let Ok(env) = std::env::var("NO_GRAPHICS") {
|
||||
|
|
@ -366,6 +366,11 @@ impl MietteHandlerOpts {
|
|||
true
|
||||
}
|
||||
}
|
||||
#[cfg(all(not(feature = "fancy-no-syscall"), not(feature = "std")))]
|
||||
{
|
||||
// In no-std environment without fancy-no-syscall, default to true
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -487,8 +492,10 @@ mod syscall {
|
|||
cfg_if! {
|
||||
if #[cfg(any(feature = "fancy-no-syscall", miri))] {
|
||||
None
|
||||
} else {
|
||||
} else if #[cfg(feature = "fancy-no-backtrace")] {
|
||||
terminal_size::terminal_size().map(|size| size.0 .0 as usize)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -498,8 +505,10 @@ mod syscall {
|
|||
cfg_if! {
|
||||
if #[cfg(feature = "fancy-no-syscall")] {
|
||||
false
|
||||
} else {
|
||||
} else if #[cfg(feature = "fancy-no-backtrace")] {
|
||||
supports_hyperlinks::on(supports_hyperlinks::Stream::Stderr)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -507,13 +516,18 @@ mod syscall {
|
|||
#[inline]
|
||||
pub(super) fn supports_color() -> bool {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "fancy-no-backtrace")] {
|
||||
if #[cfg(all(feature = "fancy", not(feature = "fancy-no-syscall")))] {
|
||||
// Standard fancy mode with full std support
|
||||
supports_color::on(supports_color::Stream::Stderr).is_some()
|
||||
} else if #[cfg(feature = "fancy-no-syscall")] {
|
||||
// In no-std environment without color support, default to no color support
|
||||
} else if #[cfg(all(feature = "fancy", feature = "fancy-no-backtrace"))] {
|
||||
// Fancy mode without backtrace but with color support
|
||||
supports_color::on(supports_color::Stream::Stderr).is_some()
|
||||
} else if #[cfg(not(feature = "std"))] {
|
||||
// No-std environment - no color support by default
|
||||
false
|
||||
} else {
|
||||
true // Fallback to assuming color support
|
||||
// All other cases - no color support
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -537,8 +551,10 @@ mod syscall {
|
|||
cfg_if! {
|
||||
if #[cfg(feature = "fancy-no-syscall")] {
|
||||
false
|
||||
} else {
|
||||
} else if #[cfg(feature = "fancy-no-backtrace")] {
|
||||
supports_unicode::on(supports_unicode::Stream::Stderr)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl Default for GraphicalTheme {
|
|||
// In no-std environments, default to no-color mode
|
||||
Self::unicode_nocolor()
|
||||
}
|
||||
#[cfg(not(feature = "fancy-no-syscall"))]
|
||||
#[cfg(all(not(feature = "fancy-no-syscall"), feature = "std"))]
|
||||
{
|
||||
match std::env::var("NO_COLOR") {
|
||||
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
||||
|
|
@ -86,6 +86,11 @@ impl Default for GraphicalTheme {
|
|||
_ => Self::unicode(),
|
||||
}
|
||||
}
|
||||
#[cfg(all(not(feature = "fancy-no-syscall"), not(feature = "std")))]
|
||||
{
|
||||
// In no-std environment, default to unicode theme
|
||||
Self::unicode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use core::str;
|
||||
use std::path::Path;
|
||||
|
||||
extern crate alloc;
|
||||
|
|
|
|||
21
src/lib.rs
21
src/lib.rs
|
|
@ -60,8 +60,8 @@
|
|||
//!
|
||||
//! ## Features
|
||||
//!
|
||||
//! - Generic [`Diagnostic`] protocol, compatible (and dependent on)
|
||||
//! [`std::error::Error`].
|
||||
//! - Generic [`Diagnostic`] protocol, compatible with `std::error::Error`.
|
||||
//! Works without the standard library: Just turn off the default `std` feature and you can use `miette` in places like embedded systems or web browsers that don't have the full standard library. You still need `alloc` for memory management.
|
||||
//! - Unique error codes on every [`Diagnostic`].
|
||||
//! - Custom links to get more details on error codes.
|
||||
//! - Super handy derive macro for defining diagnostic metadata.
|
||||
|
|
@ -95,6 +95,19 @@
|
|||
//! $ cargo add miette --features fancy
|
||||
//! ```
|
||||
//!
|
||||
//! For computers without the standard library (like microcontrollers or web browsers):
|
||||
//!
|
||||
//! ```sh
|
||||
//! $ cargo add miette --no-default-features --features derive
|
||||
//! ```
|
||||
//!
|
||||
//! Available features you can turn on or off:
|
||||
//! - `std` (on by default): Use the standard library
|
||||
//! - `derive`: Lets you automatically create error types
|
||||
//! - `fancy`: Shows pretty error messages with colors
|
||||
//! - `fancy-no-syscall`: Pretty errors without using system calls
|
||||
//! - `fancy-no-backtrace`: Pretty errors without showing the call stack
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```rust
|
||||
|
|
@ -829,10 +842,6 @@
|
|||
//! under the Apache License. Some code is taken from
|
||||
//! [`ariadne`](https://github.com/zesterer/ariadne), which is MIT licensed.
|
||||
|
||||
// For doctests that use Diagnostic derive macro
|
||||
#[cfg(test)]
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
|
|
|
|||
22
src/panic.rs
22
src/panic.rs
|
|
@ -1,4 +1,6 @@
|
|||
#[cfg(feature = "std")]
|
||||
use std::boxed::Box;
|
||||
#[cfg(feature = "std")]
|
||||
use std::{
|
||||
eprintln,
|
||||
error::Error,
|
||||
|
|
@ -7,11 +9,14 @@ use std::{
|
|||
string::{String, ToString},
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use backtrace::Backtrace;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::{Context, Diagnostic, Result};
|
||||
|
||||
/// Tells miette to render panics using its rendering engine.
|
||||
/// Makes miette show pretty error messages when your program crashes.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn set_panic_hook() {
|
||||
std::panic::set_hook(Box::new(move |info| {
|
||||
let mut message = "Something went wrong".to_string();
|
||||
|
|
@ -33,9 +38,20 @@ pub fn set_panic_hook() {
|
|||
}));
|
||||
}
|
||||
|
||||
/// Makes miette show pretty error messages when your program crashes.
|
||||
///
|
||||
/// On computers without the standard library, this function does nothing
|
||||
/// because crash hooks need the standard library to work.
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub fn set_panic_hook() {
|
||||
// Does nothing on computers without the standard library
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg(feature = "std")]
|
||||
struct Panic(String);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Display for Panic {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let msg = &self.0;
|
||||
|
|
@ -44,8 +60,10 @@ impl Display for Panic {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Error for Panic {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Diagnostic for Panic {
|
||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||
Some(Box::new(
|
||||
|
|
@ -54,6 +72,7 @@ impl Diagnostic for Panic {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Panic {
|
||||
fn backtrace() -> String {
|
||||
use std::fmt::Write;
|
||||
|
|
@ -110,6 +129,7 @@ impl Panic {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "std")]
|
||||
mod tests {
|
||||
use std::{borrow::ToOwned, error::Error};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue