From 8f2db83fb2aa06f21ea8201f9e432eef9edbaf55 Mon Sep 17 00:00:00 2001 From: Boshen Date: Thu, 22 Feb 2024 12:44:37 +0800 Subject: [PATCH] feat: add feature "fancy-no-syscall" for wasm targets --- .github/workflows/ci.yml | 4 +- Cargo.toml | 5 +++ src/handler.rs | 91 +++++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e629239..70499f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: toolchain: stable targets: wasm32-unknown-unknown - name: Check wasm target - run: cargo check --target wasm32-unknown-unknown --features fancy + run: cargo check --target wasm32-unknown-unknown --features fancy-no-syscall miri: name: Miri @@ -76,7 +76,7 @@ jobs: - name: Run tests with miri env: MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance - run: cargo miri test --all --verbose --features fancy + run: cargo miri test --all --verbose --features fancy-no-syscall minimal_versions: name: Minimal versions check diff --git a/Cargo.toml b/Cargo.toml index 92a6be4..bfe056d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ exclude = ["images/", "tests/", "miette-derive/"] thiserror = "1.0.56" miette-derive = { path = "miette-derive", version = "=7.1.0", optional = true } unicode-width = "0.1.11" +cfg-if = "1.0.0" owo-colors = { version = "4.0.0", optional = true } textwrap = { version = "0.16.0", optional = true } @@ -47,6 +48,10 @@ strip-ansi-escapes = "0.2.0" default = ["derive"] derive = ["miette-derive"] no-format-args-capture = [] +fancy-no-syscall = [ + "owo-colors", + "textwrap", +] fancy-no-backtrace = [ "owo-colors", "textwrap", diff --git a/src/handler.rs b/src/handler.rs index dcf8b13..0e90bc3 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -265,17 +265,15 @@ impl MietteHandlerOpts { let characters = match self.unicode { Some(true) => ThemeCharacters::unicode(), Some(false) => ThemeCharacters::ascii(), - None if supports_unicode::on(supports_unicode::Stream::Stderr) => { - ThemeCharacters::unicode() - } + None if syscall::supports_unicode() => ThemeCharacters::unicode(), None => ThemeCharacters::ascii(), }; let styles = if self.color == Some(false) { ThemeStyles::none() - } else if let Some(color) = supports_color::on(supports_color::Stream::Stderr) { + } else if let Some(color_has_16m) = syscall::supports_color_has_16m() { match self.rgb_colors { RgbColors::Always => ThemeStyles::rgb(), - RgbColors::Preferred if color.has_16m => ThemeStyles::rgb(), + RgbColors::Preferred if color_has_16m => ThemeStyles::rgb(), _ => ThemeStyles::ansi(), } } else if self.color == Some(true) { @@ -291,9 +289,7 @@ impl MietteHandlerOpts { #[cfg(feature = "syntect-highlighter")] let highlighter = if self.color == Some(false) { MietteHighlighter::nocolor() - } else if self.color == Some(true) - || supports_color::on(supports_color::Stream::Stderr).is_some() - { + } else if self.color == Some(true) || syscall::supports_color() { match self.highlighter { Some(highlighter) => highlighter, None => match self.rgb_colors { @@ -366,26 +362,13 @@ impl MietteHandlerOpts { if let Some(linkify) = self.linkify { linkify } else { - supports_hyperlinks::on(supports_hyperlinks::Stream::Stderr) + syscall::supports_hyperlinks() } } - #[cfg(not(miri))] pub(crate) fn get_width(&self) -> usize { - self.width.unwrap_or_else(|| { - terminal_size::terminal_size() - .unwrap_or((terminal_size::Width(80), terminal_size::Height(0))) - .0 - .0 as usize - }) - } - - #[cfg(miri)] - // miri doesn't support a syscall (specifically ioctl) - // performed by terminal_size, which causes test execution to fail - // so when miri is running we'll just fallback to a constant - pub(crate) fn get_width(&self) -> usize { - self.width.unwrap_or(80) + self.width + .unwrap_or_else(|| syscall::terminal_width().unwrap_or(80)) } } @@ -430,3 +413,63 @@ impl ReportHandler for MietteHandler { self.inner.debug(diagnostic, f) } } + +mod syscall { + use cfg_if::cfg_if; + + #[inline] + pub(super) fn terminal_width() -> Option { + cfg_if! { + if #[cfg(any(feature = "fancy-no-syscall", miri))] { + None + } else { + terminal_size::terminal_size().map(|size| size.0 .0 as usize) + } + } + } + + #[inline] + pub(super) fn supports_hyperlinks() -> bool { + cfg_if! { + if #[cfg(any(feature = "fancy-no-syscall", miri))] { + false + } else { + supports_hyperlinks::on(supports_hyperlinks::Stream::Stderr) + } + } + } + + #[cfg(feature = "syntect-highlighter")] + #[inline] + pub(super) fn supports_color() -> bool { + cfg_if! { + if #[cfg(any(feature = "fancy-no-syscall", miri))] { + false + } else { + supports_color::on(supports_color::Stream::Stderr).is_some() + } + } + } + + #[inline] + pub(super) fn supports_color_has_16m() -> Option { + cfg_if! { + if #[cfg(any(feature = "fancy-no-syscall", miri))] { + None + } else { + supports_color::on(supports_color::Stream::Stderr).map(|color| color.has_16m) + } + } + } + + #[inline] + pub(super) fn supports_unicode() -> bool { + cfg_if! { + if #[cfg(any(feature = "fancy-no-syscall", miri))] { + false + } else { + supports_unicode::on(supports_unicode::Stream::Stderr) + } + } + } +}