Skip to content

Commit 1250205

Browse files
committed
Implement Support for no_std
This brings no_std support to snafu. It now has a `std` feature which is activated by default. To make no_std support as frictionless as possible, snafu now reexports the `std::error::Error` trait as `snafu::Error` when the feature is activated and defines its own API compatible trait instead when it's disabled. Resolves #85
1 parent 0bfff3d commit 1250205

10 files changed

Lines changed: 323 additions & 96 deletions

File tree

.cirrus.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ stable_test_task:
2525
- cargo fmt --all -- --check
2626
before_cache_script: rm -rf $CARGO_HOME/registry/index
2727

28+
no_std_test_task:
29+
name: "Rust Stable (no_std)"
30+
container:
31+
image: rust:latest
32+
cpu: 1
33+
memory: 2Gi
34+
cargo_cache:
35+
folder: $CARGO_HOME/registry
36+
fingerprint_script: cat Cargo.toml
37+
setup_script:
38+
- rustup target add thumbv6m-none-eabi
39+
primary_test_script:
40+
- rustc --version
41+
- cargo build --no-default-features --target thumbv6m-none-eabi
42+
before_cache_script: rm -rf $CARGO_HOME/registry/index
43+
2844
nightly_test_task:
2945
name: "Rust Nightly"
3046
container:

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository = "https://github.com/shepmaster/snafu"
1010

1111
license = "MIT OR Apache-2.0"
1212

13-
keywords = ["error", "ergonomic", "library"]
13+
keywords = ["error", "ergonomic", "library", "no_std"]
1414
categories = ["rust-patterns"]
1515

1616
exclude = [
@@ -23,10 +23,13 @@ exclude = [
2323
all-features = true
2424

2525
[features]
26-
default = ["rust_1_30", "backtraces"]
26+
default = ["rust_1_30", "backtraces", "std"]
27+
28+
# Uses the `std::error::Error` trait instead of its own
29+
std = []
2730

2831
# Adds the backtrace type
29-
backtraces = ["snafu-derive/backtraces", "backtrace"]
32+
backtraces = ["std", "snafu-derive/backtraces", "backtrace"]
3033

3134
# Add conversion to `backtrace::Backtrace`
3235
backtrace-crate = ["backtraces"]

compatibility-tests/without-backtrace/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ authors = ["Jake Goulding <[email protected]>"]
55
edition = "2018"
66

77
[dependencies]
8-
snafu = { path = "../..", default-features = false, features = ["rust_1_30"] }
8+
snafu = { path = "../..", default-features = false, features = ["rust_1_30", "std"] }

snafu-derive/src/lib.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> {
12251225
let backtrace_field = match *backtrace_field {
12261226
Some(ref field) => {
12271227
let name = &field.name;
1228-
quote! { #name: std::default::Default::default(), }
1228+
quote! { #name: core::default::Default::default(), }
12291229
}
12301230
None => quote! {},
12311231
};
@@ -1235,7 +1235,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> {
12351235
.zip(user_fields)
12361236
.map(|(gen_ty, f)| {
12371237
let Field { ref ty, .. } = *f;
1238-
quote! { #gen_ty: std::convert::Into<#ty> }
1238+
quote! { #gen_ty: core::convert::Into<#ty> }
12391239
})
12401240
.chain(self.0.provided_where_clauses())
12411241
.collect();
@@ -1246,16 +1246,16 @@ impl<'a> quote::ToTokens for ContextSelector<'a> {
12461246
quote! {
12471247
impl<#(#generic_names,)*> #selector_name
12481248
{
1249-
#visibility fn fail<#(#original_generics_without_defaults,)* __T>(self) -> std::result::Result<__T, #parameterized_enum_name>
1249+
#visibility fn fail<#(#original_generics_without_defaults,)* __T>(self) -> core::result::Result<__T, #parameterized_enum_name>
12501250
where
12511251
#(#where_clauses),*
12521252
{
12531253
let Self { #(#names),* } = self;
12541254
let error = #enum_name::#variant_name {
12551255
#backtrace_field
1256-
#( #names: std::convert::Into::into(#names2) ),*
1256+
#( #names: core::convert::Into::into(#names2) ),*
12571257
};
1258-
std::result::Result::Err(error)
1258+
core::result::Result::Err(error)
12591259
}
12601260
}
12611261
}
@@ -1294,7 +1294,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> {
12941294
quote! {
12951295
impl#generics_list snafu::IntoError<#parameterized_enum_name> for #selector_name
12961296
where
1297-
#parameterized_enum_name: std::error::Error + snafu::ErrorCompat,
1297+
#parameterized_enum_name: snafu::Error + snafu::ErrorCompat,
12981298
#(#where_clauses),*
12991299
{
13001300
type Source = #source_ty;
@@ -1381,11 +1381,11 @@ impl<'a> quote::ToTokens for DisplayImpl<'a> {
13811381

13821382
stream.extend({
13831383
quote! {
1384-
impl<#(#original_generics),*> std::fmt::Display for #parameterized_enum_name
1384+
impl<#(#original_generics),*> core::fmt::Display for #parameterized_enum_name
13851385
where
13861386
#(#where_clauses),*
13871387
{
1388-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1388+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
13891389
#[allow(unused_variables)]
13901390
match *self {
13911391
#(#variants_to_display)*
@@ -1437,13 +1437,13 @@ impl<'a> ErrorImpl<'a> {
14371437
} = *source_field;
14381438
quote! {
14391439
#enum_name::#variant_name { ref #field_name, .. } => {
1440-
std::option::Option::Some(#field_name.as_error_source())
1440+
core::option::Option::Some(#field_name.as_error_source())
14411441
}
14421442
}
14431443
}
14441444
None => {
14451445
quote! {
1446-
#enum_name::#variant_name { .. } => { std::option::Option::None }
1446+
#enum_name::#variant_name { .. } => { core::option::Option::None }
14471447
}
14481448
}
14491449
}
@@ -1471,7 +1471,7 @@ impl<'a> quote::ToTokens for ErrorImpl<'a> {
14711471
let variants_to_source = &self.variants_to_source();
14721472

14731473
let cause_fn = quote! {
1474-
fn cause(&self) -> Option<&std::error::Error> {
1474+
fn cause(&self) -> Option<&snafu::Error> {
14751475
use snafu::AsErrorSource;
14761476
match *self {
14771477
#(#variants_to_source)*
@@ -1481,7 +1481,7 @@ impl<'a> quote::ToTokens for ErrorImpl<'a> {
14811481

14821482
let source_fn = if cfg!(feature = "rust_1_30") {
14831483
quote! {
1484-
fn source(&self) -> Option<&(std::error::Error + 'static)> {
1484+
fn source(&self) -> Option<&(snafu::Error + 'static)> {
14851485
use snafu::AsErrorSource;
14861486
match *self {
14871487
#(#variants_to_source)*
@@ -1494,9 +1494,9 @@ impl<'a> quote::ToTokens for ErrorImpl<'a> {
14941494

14951495
stream.extend({
14961496
quote! {
1497-
impl<#(#original_generics),*> std::error::Error for #parameterized_enum_name
1497+
impl<#(#original_generics),*> snafu::Error for #parameterized_enum_name
14981498
where
1499-
Self: std::fmt::Debug + std::fmt::Display,
1499+
Self: core::fmt::Debug + core::fmt::Display,
15001500
#(#where_clauses),*
15011501
{
15021502
#description_fn
@@ -1537,11 +1537,11 @@ impl<'a> ErrorCompatImpl<'a> {
15371537
..
15381538
} = *backtrace_field;
15391539
quote! {
1540-
#enum_name::#variant_name { ref #field_name, .. } => { std::option::Option::Some(#field_name) }
1540+
#enum_name::#variant_name { ref #field_name, .. } => { core::option::Option::Some(#field_name) }
15411541
}
15421542
} else {
15431543
quote! {
1544-
#enum_name::#variant_name { .. } => { std::option::Option::None }
1544+
#enum_name::#variant_name { .. } => { core::option::Option::None }
15451545
}
15461546
}
15471547
}).collect()
@@ -1602,20 +1602,20 @@ impl StructInfo {
16021602

16031603
let description_fn = quote! {
16041604
fn description(&self) -> &str {
1605-
std::error::Error::description(&self.0)
1605+
snafu::Error::description(&self.0)
16061606
}
16071607
};
16081608

16091609
let cause_fn = quote! {
1610-
fn cause(&self) -> Option<&std::error::Error> {
1611-
std::error::Error::cause(&self.0)
1610+
fn cause(&self) -> Option<&snafu::Error> {
1611+
snafu::Error::cause(&self.0)
16121612
}
16131613
};
16141614

16151615
let source_fn = if cfg!(feature = "rust_1_30") {
16161616
quote! {
1617-
fn source(&self) -> Option<&(std::error::Error + 'static)> {
1618-
std::error::Error::source(&self.0)
1617+
fn source(&self) -> Option<&(snafu::Error + 'static)> {
1618+
snafu::Error::source(&self.0)
16191619
}
16201620
}
16211621
} else {
@@ -1633,7 +1633,7 @@ impl StructInfo {
16331633
};
16341634

16351635
let error_impl = quote! {
1636-
impl#generics std::error::Error for #parameterized_struct_name
1636+
impl#generics snafu::Error for #parameterized_struct_name
16371637
where
16381638
#(#where_clauses),*
16391639
{
@@ -1653,18 +1653,18 @@ impl StructInfo {
16531653
};
16541654

16551655
let display_impl = quote! {
1656-
impl#generics std::fmt::Display for #parameterized_struct_name
1656+
impl#generics core::fmt::Display for #parameterized_struct_name
16571657
where
16581658
#(#where_clauses),*
16591659
{
1660-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1661-
std::fmt::Display::fmt(&self.0, f)
1660+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1661+
core::fmt::Display::fmt(&self.0, f)
16621662
}
16631663
}
16641664
};
16651665

16661666
let from_impl = quote! {
1667-
impl#generics std::convert::From<#inner_type> for #parameterized_struct_name
1667+
impl#generics core::convert::From<#inner_type> for #parameterized_struct_name
16681668
where
16691669
#(#where_clauses),*
16701670
{

src/futures/try_future.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
//!
33
//! [`TryFuture`]: futures_core::future::TryFuture
44
5-
use futures_core::future::TryFuture;
6-
use pin_project::unsafe_project;
7-
use std::{
5+
use core::{
86
marker::PhantomData,
97
pin::Pin,
108
task::{Context as TaskContext, Poll},
119
};
12-
use {ErrorCompat, IntoError};
10+
use futures_core::future::TryFuture;
11+
use pin_project::unsafe_project;
12+
use {Error, ErrorCompat, IntoError};
1313

1414
/// Additions to [`TryFuture`].
1515
pub trait TryFutureExt: TryFuture + Sized {
@@ -49,7 +49,7 @@ pub trait TryFutureExt: TryFuture + Sized {
4949
fn context<C, E>(self, context: C) -> Context<Self, C, E>
5050
where
5151
C: IntoError<E, Source = Self::Error>,
52-
E: std::error::Error + ErrorCompat;
52+
E: Error + ErrorCompat;
5353

5454
/// Extend a [`TryFuture`]'s error with lazily-generated context-sensitive
5555
/// information.
@@ -88,7 +88,7 @@ pub trait TryFutureExt: TryFuture + Sized {
8888
where
8989
F: FnOnce() -> C,
9090
C: IntoError<E, Source = Self::Error>,
91-
E: std::error::Error + ErrorCompat;
91+
E: Error + ErrorCompat;
9292
}
9393

9494
impl<Fut> TryFutureExt for Fut
@@ -98,7 +98,7 @@ where
9898
fn context<C, E>(self, context: C) -> Context<Self, C, E>
9999
where
100100
C: IntoError<E, Source = Self::Error>,
101-
E: std::error::Error + ErrorCompat,
101+
E: Error + ErrorCompat,
102102
{
103103
Context {
104104
inner: self,
@@ -111,7 +111,7 @@ where
111111
where
112112
F: FnOnce() -> C,
113113
C: IntoError<E, Source = Self::Error>,
114-
E: std::error::Error + ErrorCompat,
114+
E: Error + ErrorCompat,
115115
{
116116
WithContext {
117117
inner: self,
@@ -138,7 +138,7 @@ impl<Fut, C, E> TryFuture for Context<Fut, C, E>
138138
where
139139
Fut: TryFuture,
140140
C: IntoError<E, Source = Fut::Error>,
141-
E: std::error::Error + ErrorCompat,
141+
E: Error + ErrorCompat,
142142
{
143143
type Ok = Fut::Ok;
144144
type Error = E;
@@ -178,7 +178,7 @@ where
178178
Fut: TryFuture,
179179
F: FnOnce() -> C,
180180
C: IntoError<E, Source = Fut::Error>,
181-
E: std::error::Error + ErrorCompat,
181+
E: Error + ErrorCompat,
182182
{
183183
type Ok = Fut::Ok;
184184
type Error = E;

src/futures/try_stream.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
//!
33
//! [`TryStream`]: futures_core::TryStream
44
5-
use futures_core::stream::TryStream;
6-
use pin_project::unsafe_project;
7-
use std::{
5+
use core::{
86
marker::PhantomData,
97
pin::Pin,
108
task::{Context as TaskContext, Poll},
119
};
12-
use {ErrorCompat, IntoError};
10+
use futures_core::stream::TryStream;
11+
use pin_project::unsafe_project;
12+
use {Error, ErrorCompat, IntoError};
1313

1414
/// Additions to [`TryStream`].
1515
pub trait TryStreamExt: TryStream + Sized {
@@ -50,7 +50,7 @@ pub trait TryStreamExt: TryStream + Sized {
5050
fn context<C, E>(self, context: C) -> Context<Self, C, E>
5151
where
5252
C: IntoError<E, Source = Self::Error> + Clone,
53-
E: std::error::Error + ErrorCompat;
53+
E: Error + ErrorCompat;
5454

5555
/// Extend a [`TryStream`]'s error with lazily-generated
5656
/// context-sensitive information.
@@ -90,7 +90,7 @@ pub trait TryStreamExt: TryStream + Sized {
9090
where
9191
F: FnMut() -> C,
9292
C: IntoError<E, Source = Self::Error>,
93-
E: std::error::Error + ErrorCompat;
93+
E: Error + ErrorCompat;
9494
}
9595

9696
impl<St> TryStreamExt for St
@@ -100,7 +100,7 @@ where
100100
fn context<C, E>(self, context: C) -> Context<Self, C, E>
101101
where
102102
C: IntoError<E, Source = Self::Error> + Clone,
103-
E: std::error::Error + ErrorCompat,
103+
E: Error + ErrorCompat,
104104
{
105105
Context {
106106
inner: self,
@@ -113,7 +113,7 @@ where
113113
where
114114
F: FnMut() -> C,
115115
C: IntoError<E, Source = Self::Error>,
116-
E: std::error::Error + ErrorCompat,
116+
E: Error + ErrorCompat,
117117
{
118118
WithContext {
119119
inner: self,
@@ -140,7 +140,7 @@ impl<St, C, E> TryStream for Context<St, C, E>
140140
where
141141
St: TryStream,
142142
C: IntoError<E, Source = St::Error> + Clone,
143-
E: std::error::Error + ErrorCompat,
143+
E: Error + ErrorCompat,
144144
{
145145
type Ok = St::Ok;
146146
type Error = E;
@@ -183,7 +183,7 @@ where
183183
St: TryStream,
184184
F: FnMut() -> C,
185185
C: IntoError<E, Source = St::Error>,
186-
E: std::error::Error + ErrorCompat,
186+
E: Error + ErrorCompat,
187187
{
188188
type Ok = St::Ok;
189189
type Error = E;

0 commit comments

Comments
 (0)