Skip to content

Commit 18c217f

Browse files
committed
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
1 parent 79fbd0a commit 18c217f

File tree

8 files changed

+83
-31
lines changed

8 files changed

+83
-31
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ jobs:
6868
- name: Check wasm target
6969
run: cargo check --target wasm32-unknown-unknown --features fancy-no-syscall
7070

71+
no-std:
72+
name: Check no-std build
73+
runs-on: ubuntu-latest
74+
steps:
75+
- uses: actions/checkout@v4
76+
- name: Install Rust
77+
uses: dtolnay/rust-toolchain@master
78+
with:
79+
toolchain: stable
80+
targets: wasm32-unknown-unknown
81+
- name: Check no-std core build
82+
run: cargo check --target wasm32-unknown-unknown --no-default-features
83+
- name: Check no-std with fancy-no-syscall
84+
run: cargo check --target wasm32-unknown-unknown --no-default-features --features fancy-no-syscall
85+
7186
miri:
7287
name: Miri
7388
runs-on: ubuntu-latest

src/diagnostic_impls.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ use core::{convert::Infallible, fmt::Display};
88

99
use crate::{Diagnostic, LabeledSpan, Severity, SourceCode};
1010

11+
#[cfg(not(feature = "std"))]
12+
impl crate::StdError for Infallible {}
13+
1114
impl Diagnostic for Infallible {
1215
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
1316
match *self {}

src/eyreish/wrapper.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,16 @@ impl<C> StdError for WithSourceCode<Report, C> {
209209
}
210210
}
211211

212-
#[cfg(test)]
212+
#[cfg(all(test, feature = "std"))]
213213
mod tests {
214-
214+
#[cfg(feature = "fancy")]
215+
use std::format;
215216
use std::{
216217
boxed::Box,
217218
string::{String, ToString},
218219
};
220+
#[cfg(feature = "fancy")]
221+
use std::{vec, vec::Vec};
219222
use thiserror::Error;
220223

221224
use crate::{Diagnostic, LabeledSpan, Report, SourceCode, SourceSpan};

src/handler.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,27 @@ impl MietteHandlerOpts {
345345
}
346346
}
347347

348+
#[allow(clippy::manual_unwrap_or)]
348349
pub(crate) fn is_graphical(&self) -> bool {
349350
if let Some(force_narrated) = self.force_narrated {
350351
!force_narrated
351352
} else if let Some(force_graphical) = self.force_graphical {
352353
force_graphical
353-
} else if let Ok(env) = std::env::var("NO_GRAPHICS") {
354-
env == "0"
355354
} else {
356-
true
355+
#[cfg(feature = "fancy-no-syscall")]
356+
{
357+
// In no-std environment, assume graphics are available
358+
true
359+
}
360+
#[cfg(not(feature = "fancy-no-syscall"))]
361+
{
362+
// In std environment, check NO_GRAPHICS env var
363+
if let Ok(env) = std::env::var("NO_GRAPHICS") {
364+
env == "0"
365+
} else {
366+
true
367+
}
368+
}
357369
}
358370
}
359371

@@ -501,7 +513,7 @@ mod syscall {
501513
// In no-std environment without color support, default to no color support
502514
false
503515
} else {
504-
supports_color::on(supports_color::Stream::Stderr).is_some()
516+
true // Fallback to assuming color support
505517
}
506518
}
507519
}
@@ -515,7 +527,7 @@ mod syscall {
515527
// In no-std environment without color support, default to no RGB color support
516528
Some(false)
517529
} else {
518-
supports_color::on(supports_color::Stream::Stderr).map(|color| color.has_16m)
530+
Some(true) // Fallback to assuming RGB support
519531
}
520532
}
521533
}

src/handlers/graphical.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ impl GraphicalReportHandler {
588588
// The snippets will overlap, so we create one Big Chunky Boi
589589
let left_end = left.offset() + left.len();
590590
let right_end = right.offset() + right.len();
591-
let new_end = std::cmp::max(left_end, right_end);
591+
let new_end = core::cmp::max(left_end, right_end);
592592

593593
let new_span = LabeledSpan::new(
594594
left.label().map(String::from),
@@ -655,7 +655,7 @@ impl GraphicalReportHandler {
655655
num_highlights += 1;
656656
}
657657
}
658-
max_gutter = std::cmp::max(max_gutter, num_highlights);
658+
max_gutter = core::cmp::max(max_gutter, num_highlights);
659659
}
660660

661661
// Oh and one more thing: We need to figure out how much room our line
@@ -1179,7 +1179,7 @@ impl GraphicalReportHandler {
11791179
.style(hl.style)
11801180
.to_string(),
11811181
);
1182-
highest = std::cmp::max(highest, end);
1182+
highest = core::cmp::max(highest, end);
11831183

11841184
(hl, vbar_offset)
11851185
})

src/handlers/theme.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,20 @@ impl GraphicalTheme {
7171

7272
impl Default for GraphicalTheme {
7373
fn default() -> Self {
74-
match std::env::var("NO_COLOR") {
75-
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
76-
Self::none()
74+
#[cfg(feature = "fancy-no-syscall")]
75+
{
76+
// In no-std environments, default to no-color mode
77+
Self::unicode_nocolor()
78+
}
79+
#[cfg(not(feature = "fancy-no-syscall"))]
80+
{
81+
match std::env::var("NO_COLOR") {
82+
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
83+
Self::none()
84+
}
85+
Ok(string) if string != "0" => Self::unicode_nocolor(),
86+
_ => Self::unicode(),
7787
}
78-
Ok(string) if string != "0" => Self::unicode_nocolor(),
79-
_ => Self::unicode(),
8088
}
8189
}
8290
}

src/highlighters/mod.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! * `syntect-highlighter` - Enables [`syntect`](https://docs.rs/syntect/latest/syntect/) syntax highlighting support via the [`SyntectHighlighter`]
1212
//!
1313
14-
use std::{ops::Deref, sync::Arc};
14+
use core::ops::Deref;
1515

1616
extern crate alloc;
1717
use alloc::boxed::Box;
@@ -83,21 +83,28 @@ impl MietteHighlighter {
8383
}
8484

8585
impl Default for MietteHighlighter {
86-
#[cfg(feature = "syntect-highlighter")]
8786
fn default() -> Self {
88-
use std::io::IsTerminal;
89-
match std::env::var("NO_COLOR") {
90-
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
91-
//TODO: should use ANSI styling instead of 24-bit truecolor here
92-
Self(Arc::new(SyntectHighlighter::default()))
87+
#[cfg(all(feature = "syntect-highlighter", not(feature = "fancy-no-syscall")))]
88+
{
89+
use std::io::IsTerminal;
90+
match std::env::var("NO_COLOR") {
91+
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
92+
//TODO: should use ANSI styling instead of 24-bit truecolor here
93+
Self(Arc::new(SyntectHighlighter::default()))
94+
}
95+
Ok(string) if string != "0" => MietteHighlighter::nocolor(),
96+
_ => Self(Arc::new(SyntectHighlighter::default())),
9397
}
94-
Ok(string) if string != "0" => MietteHighlighter::nocolor(),
95-
_ => Self(Arc::new(SyntectHighlighter::default())),
9698
}
97-
}
98-
#[cfg(not(feature = "syntect-highlighter"))]
99-
fn default() -> Self {
100-
MietteHighlighter::nocolor()
99+
#[cfg(all(feature = "syntect-highlighter", feature = "fancy-no-syscall"))]
100+
{
101+
// In no-std environment, use syntect but without terminal detection
102+
Self(Arc::new(SyntectHighlighter::default()))
103+
}
104+
#[cfg(not(feature = "syntect-highlighter"))]
105+
{
106+
MietteHighlighter::nocolor()
107+
}
101108
}
102109
}
103110

@@ -107,8 +114,8 @@ impl<T: Highlighter + Send + Sync + 'static> From<T> for MietteHighlighter {
107114
}
108115
}
109116

110-
impl std::fmt::Debug for MietteHighlighter {
111-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117+
impl core::fmt::Debug for MietteHighlighter {
118+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
112119
write!(f, "MietteHighlighter(...)")
113120
}
114121
}

src/protocol.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ use alloc::boxed::Box;
99
use alloc::string::String;
1010
use core::fmt::{self, Display};
1111
use core::ops;
12+
#[cfg(feature = "std")]
1213
use core::panic::Location;
1314
#[cfg(feature = "std")]
1415
use std::fs;
1516

1617
#[cfg(feature = "serde")]
1718
use serde::{Deserialize, Serialize};
1819

19-
use crate::{DiagnosticError, MietteError};
20+
use crate::MietteError;
2021

2122
/// Adds rich metadata to your Error that can be used by
2223
/// [`Report`](crate::Report) to print really nice and human-friendly error
@@ -172,6 +173,9 @@ impl From<String> for Box<dyn Diagnostic + Send + Sync> {
172173
}
173174
}
174175

176+
#[cfg(feature = "std")]
177+
use crate::DiagnosticError;
178+
175179
#[cfg(feature = "std")]
176180
impl From<Box<dyn std::error::Error + Send + Sync>> for Box<dyn Diagnostic + Send + Sync> {
177181
fn from(s: Box<dyn std::error::Error + Send + Sync>) -> Self {

0 commit comments

Comments
 (0)