mirror of https://github.com/zkat/miette.git
Add CI job for no-std build verification and fix Infallible StdError implementation
- Add dedicated no-std CI job that builds for wasm32-unknown-unknown target - Fix Infallible StdError implementation for no-std environments The CI job validates: 1. Core no-std functionality (no default features) 2. fancy-no-syscall feature set compatible with no-std environments
This commit is contained in:
parent
79fbd0a07d
commit
18c217f0dc
|
|
@ -68,6 +68,21 @@ jobs:
|
||||||
- name: Check wasm target
|
- name: Check wasm target
|
||||||
run: cargo check --target wasm32-unknown-unknown --features fancy-no-syscall
|
run: cargo check --target wasm32-unknown-unknown --features fancy-no-syscall
|
||||||
|
|
||||||
|
no-std:
|
||||||
|
name: Check no-std build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
targets: wasm32-unknown-unknown
|
||||||
|
- name: Check no-std core build
|
||||||
|
run: cargo check --target wasm32-unknown-unknown --no-default-features
|
||||||
|
- name: Check no-std with fancy-no-syscall
|
||||||
|
run: cargo check --target wasm32-unknown-unknown --no-default-features --features fancy-no-syscall
|
||||||
|
|
||||||
miri:
|
miri:
|
||||||
name: Miri
|
name: Miri
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ use core::{convert::Infallible, fmt::Display};
|
||||||
|
|
||||||
use crate::{Diagnostic, LabeledSpan, Severity, SourceCode};
|
use crate::{Diagnostic, LabeledSpan, Severity, SourceCode};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
impl crate::StdError for Infallible {}
|
||||||
|
|
||||||
impl Diagnostic for Infallible {
|
impl Diagnostic for Infallible {
|
||||||
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
match *self {}
|
match *self {}
|
||||||
|
|
|
||||||
|
|
@ -209,13 +209,16 @@ impl<C> StdError for WithSourceCode<Report, C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(all(test, feature = "std"))]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
#[cfg(feature = "fancy")]
|
||||||
|
use std::format;
|
||||||
use std::{
|
use std::{
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "fancy")]
|
||||||
|
use std::{vec, vec::Vec};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{Diagnostic, LabeledSpan, Report, SourceCode, SourceSpan};
|
use crate::{Diagnostic, LabeledSpan, Report, SourceCode, SourceSpan};
|
||||||
|
|
|
||||||
|
|
@ -345,15 +345,27 @@ impl MietteHandlerOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::manual_unwrap_or)]
|
||||||
pub(crate) fn is_graphical(&self) -> bool {
|
pub(crate) fn is_graphical(&self) -> bool {
|
||||||
if let Some(force_narrated) = self.force_narrated {
|
if let Some(force_narrated) = self.force_narrated {
|
||||||
!force_narrated
|
!force_narrated
|
||||||
} else if let Some(force_graphical) = self.force_graphical {
|
} else if let Some(force_graphical) = self.force_graphical {
|
||||||
force_graphical
|
force_graphical
|
||||||
} else if let Ok(env) = std::env::var("NO_GRAPHICS") {
|
|
||||||
env == "0"
|
|
||||||
} else {
|
} else {
|
||||||
true
|
#[cfg(feature = "fancy-no-syscall")]
|
||||||
|
{
|
||||||
|
// In no-std environment, assume graphics are available
|
||||||
|
true
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "fancy-no-syscall"))]
|
||||||
|
{
|
||||||
|
// In std environment, check NO_GRAPHICS env var
|
||||||
|
if let Ok(env) = std::env::var("NO_GRAPHICS") {
|
||||||
|
env == "0"
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -501,7 +513,7 @@ mod syscall {
|
||||||
// In no-std environment without color support, default to no color support
|
// In no-std environment without color support, default to no color support
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
supports_color::on(supports_color::Stream::Stderr).is_some()
|
true // Fallback to assuming color support
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -515,7 +527,7 @@ mod syscall {
|
||||||
// In no-std environment without color support, default to no RGB color support
|
// In no-std environment without color support, default to no RGB color support
|
||||||
Some(false)
|
Some(false)
|
||||||
} else {
|
} else {
|
||||||
supports_color::on(supports_color::Stream::Stderr).map(|color| color.has_16m)
|
Some(true) // Fallback to assuming RGB support
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -588,7 +588,7 @@ impl GraphicalReportHandler {
|
||||||
// The snippets will overlap, so we create one Big Chunky Boi
|
// The snippets will overlap, so we create one Big Chunky Boi
|
||||||
let left_end = left.offset() + left.len();
|
let left_end = left.offset() + left.len();
|
||||||
let right_end = right.offset() + right.len();
|
let right_end = right.offset() + right.len();
|
||||||
let new_end = std::cmp::max(left_end, right_end);
|
let new_end = core::cmp::max(left_end, right_end);
|
||||||
|
|
||||||
let new_span = LabeledSpan::new(
|
let new_span = LabeledSpan::new(
|
||||||
left.label().map(String::from),
|
left.label().map(String::from),
|
||||||
|
|
@ -655,7 +655,7 @@ impl GraphicalReportHandler {
|
||||||
num_highlights += 1;
|
num_highlights += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
max_gutter = std::cmp::max(max_gutter, num_highlights);
|
max_gutter = core::cmp::max(max_gutter, num_highlights);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Oh and one more thing: We need to figure out how much room our line
|
// Oh and one more thing: We need to figure out how much room our line
|
||||||
|
|
@ -1179,7 +1179,7 @@ impl GraphicalReportHandler {
|
||||||
.style(hl.style)
|
.style(hl.style)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
highest = std::cmp::max(highest, end);
|
highest = core::cmp::max(highest, end);
|
||||||
|
|
||||||
(hl, vbar_offset)
|
(hl, vbar_offset)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -71,12 +71,20 @@ impl GraphicalTheme {
|
||||||
|
|
||||||
impl Default for GraphicalTheme {
|
impl Default for GraphicalTheme {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
match std::env::var("NO_COLOR") {
|
#[cfg(feature = "fancy-no-syscall")]
|
||||||
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
{
|
||||||
Self::none()
|
// In no-std environments, default to no-color mode
|
||||||
|
Self::unicode_nocolor()
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "fancy-no-syscall"))]
|
||||||
|
{
|
||||||
|
match std::env::var("NO_COLOR") {
|
||||||
|
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
||||||
|
Self::none()
|
||||||
|
}
|
||||||
|
Ok(string) if string != "0" => Self::unicode_nocolor(),
|
||||||
|
_ => Self::unicode(),
|
||||||
}
|
}
|
||||||
Ok(string) if string != "0" => Self::unicode_nocolor(),
|
|
||||||
_ => Self::unicode(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
//! * `syntect-highlighter` - Enables [`syntect`](https://docs.rs/syntect/latest/syntect/) syntax highlighting support via the [`SyntectHighlighter`]
|
//! * `syntect-highlighter` - Enables [`syntect`](https://docs.rs/syntect/latest/syntect/) syntax highlighting support via the [`SyntectHighlighter`]
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::{ops::Deref, sync::Arc};
|
use core::ops::Deref;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
@ -83,21 +83,28 @@ impl MietteHighlighter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MietteHighlighter {
|
impl Default for MietteHighlighter {
|
||||||
#[cfg(feature = "syntect-highlighter")]
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
use std::io::IsTerminal;
|
#[cfg(all(feature = "syntect-highlighter", not(feature = "fancy-no-syscall")))]
|
||||||
match std::env::var("NO_COLOR") {
|
{
|
||||||
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
use std::io::IsTerminal;
|
||||||
//TODO: should use ANSI styling instead of 24-bit truecolor here
|
match std::env::var("NO_COLOR") {
|
||||||
Self(Arc::new(SyntectHighlighter::default()))
|
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
||||||
|
//TODO: should use ANSI styling instead of 24-bit truecolor here
|
||||||
|
Self(Arc::new(SyntectHighlighter::default()))
|
||||||
|
}
|
||||||
|
Ok(string) if string != "0" => MietteHighlighter::nocolor(),
|
||||||
|
_ => Self(Arc::new(SyntectHighlighter::default())),
|
||||||
}
|
}
|
||||||
Ok(string) if string != "0" => MietteHighlighter::nocolor(),
|
|
||||||
_ => Self(Arc::new(SyntectHighlighter::default())),
|
|
||||||
}
|
}
|
||||||
}
|
#[cfg(all(feature = "syntect-highlighter", feature = "fancy-no-syscall"))]
|
||||||
#[cfg(not(feature = "syntect-highlighter"))]
|
{
|
||||||
fn default() -> Self {
|
// In no-std environment, use syntect but without terminal detection
|
||||||
MietteHighlighter::nocolor()
|
Self(Arc::new(SyntectHighlighter::default()))
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "syntect-highlighter"))]
|
||||||
|
{
|
||||||
|
MietteHighlighter::nocolor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,8 +114,8 @@ impl<T: Highlighter + Send + Sync + 'static> From<T> for MietteHighlighter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for MietteHighlighter {
|
impl core::fmt::Debug for MietteHighlighter {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "MietteHighlighter(...)")
|
write!(f, "MietteHighlighter(...)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use alloc::boxed::Box;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::fmt::{self, Display};
|
use core::fmt::{self, Display};
|
||||||
use core::ops;
|
use core::ops;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
use core::panic::Location;
|
use core::panic::Location;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
@ -16,7 +17,7 @@ use std::fs;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{DiagnosticError, MietteError};
|
use crate::MietteError;
|
||||||
|
|
||||||
/// Adds rich metadata to your Error that can be used by
|
/// Adds rich metadata to your Error that can be used by
|
||||||
/// [`Report`](crate::Report) to print really nice and human-friendly error
|
/// [`Report`](crate::Report) to print really nice and human-friendly error
|
||||||
|
|
@ -172,6 +173,9 @@ impl From<String> for Box<dyn Diagnostic + Send + Sync> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use crate::DiagnosticError;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl From<Box<dyn std::error::Error + Send + Sync>> for Box<dyn Diagnostic + Send + Sync> {
|
impl From<Box<dyn std::error::Error + Send + Sync>> for Box<dyn Diagnostic + Send + Sync> {
|
||||||
fn from(s: Box<dyn std::error::Error + Send + Sync>) -> Self {
|
fn from(s: Box<dyn std::error::Error + Send + Sync>) -> Self {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue