Skip to content
This repository was archived by the owner on Aug 16, 2021. It is now read-only.

Commit 9abe167

Browse files
committed
[WIP] Core support.
1 parent c81a5bb commit 9abe167

File tree

7 files changed

+85
-35
lines changed

7 files changed

+85
-35
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ repository = "https://github.com/brson/error-chain"
1515
license = "MIT/Apache-2.0"
1616

1717
[features]
18-
default = ["backtrace", "example_generated"]
18+
default = ["backtrace", "example_generated", "alloc"]
1919
example_generated = []
20+
alloc = []
2021

2122
[dependencies]
2223
backtrace = { version = "0.3", optional = true }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/error_chain.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ macro_rules! error_chain_processed {
2727
$( $rest )*
2828
}
2929
/// Convenient wrapper around `std::Result`.
30-
pub type $result_name<T> = ::std::result::Result<T, $error_name>;
30+
pub type $result_name<T> = $crate::Result<T, $error_name>;
3131
};
3232
// Without `Result` wrapper.
3333
(
@@ -109,13 +109,13 @@ macro_rules! error_chain_processed {
109109
}
110110
}
111111

112-
impl ::std::error::Error for $error_name {
112+
impl $crate::Error for $error_name {
113113
fn description(&self) -> &str {
114114
self.kind.description()
115115
}
116116

117-
fn cause(&self) -> Option<&::std::error::Error> {
118-
match self.state.next_error {
117+
fn cause(&self) -> Option<&$crate::Error> {
118+
match self.state.next_error() {
119119
Some(ref c) => Some(&**c),
120120
None => {
121121
match self.kind {
@@ -132,11 +132,7 @@ macro_rules! error_chain_processed {
132132
}
133133
}
134134

135-
impl ::std::fmt::Display for $error_name {
136-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
137-
::std::fmt::Display::fmt(&self.kind, f)
138-
}
139-
}
135+
if_alloc!($error_name $error_kind_name);
140136

141137
$(
142138
$(#[$meta_links])*
@@ -179,14 +175,6 @@ macro_rules! error_chain_processed {
179175
}
180176
}
181177

182-
impl ::std::ops::Deref for $error_name {
183-
type Target = $error_kind_name;
184-
185-
fn deref(&self) -> &Self::Target {
186-
&self.kind
187-
}
188-
}
189-
190178

191179
// The ErrorKind type
192180
// --------------
@@ -213,7 +201,7 @@ macro_rules! error_chain_processed {
213201
$(
214202
$(#[$meta_foreign_links])*
215203
$foreign_link_variant(err: $foreign_link_error_path) {
216-
description(::std::error::Error::description(err))
204+
description($crate::Error::description(err))
217205
display("{}", err)
218206
}
219207
) *
@@ -329,7 +317,7 @@ macro_rules! impl_extract_backtrace {
329317
($error_name: ident
330318
$error_kind_name: ident
331319
$([$link_error_path: path, $(#[$meta_links: meta])*])*) => {
332-
fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
320+
fn extract_backtrace(e: &($crate::Error + Send + 'static))
333321
-> Option<Option<::std::sync::Arc<$crate::Backtrace>>> {
334322
if let Some(e) = e.downcast_ref::<$error_name>() {
335323
return Some(e.state.backtrace.clone());
@@ -360,3 +348,31 @@ macro_rules! impl_extract_backtrace {
360348
$error_kind_name: ident
361349
$([$link_error_path: path, $(#[$meta_links: meta])*])*) => {}
362350
}
351+
352+
#[macro_export]
353+
#[doc(hidden)]
354+
#[cfg(feature = "alloc")]
355+
macro_rules! if_alloc {
356+
($error_name:ident $error_kind_name: ident) => {
357+
impl ::std::fmt::Display for $error_name {
358+
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
359+
::std::fmt::Display::fmt(&self.kind, f)
360+
}
361+
}
362+
363+
impl ::std::ops::Deref for $error_name {
364+
type Target = $error_kind_name;
365+
366+
fn deref(&self) -> &Self::Target {
367+
&self.kind
368+
}
369+
}
370+
}
371+
}
372+
373+
#[macro_export]
374+
#[doc(hidden)]
375+
#[cfg(not(feature = "alloc"))]
376+
macro_rules! if_alloc {
377+
($error_name:ident $error_kind_name: ident) => {}
378+
}

src/lib.rs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![warn(missing_docs)]
2-
31
//! A library for consistent and reliable error handling
42
//!
53
//! This crate defines an opinionated strategy for error handling in Rust,
@@ -251,13 +249,35 @@
251249
//! [error-type]: https://github.com/DanielKeep/rust-error-type
252250
//! [quick-error]: https://github.com/tailhook/quick-error
253251
252+
#![warn(missing_docs)]
253+
#![cfg_attr(not(feature = "alloc"), no_std)]
254+
254255
#[cfg(feature = "backtrace")]
255256
extern crate backtrace;
256257

257-
use std::error;
258-
use std::iter::Iterator;
259-
#[cfg(feature = "backtrace")]
260-
use std::sync::Arc;
258+
#[cfg(feature = "alloc")]
259+
mod alloc {
260+
pub use std::error;
261+
pub use std::iter::Iterator;
262+
#[cfg(feature = "backtrace")]
263+
pub use std::sync::Arc;
264+
pub use std::result::Result;
265+
}
266+
#[cfg(not(feature = "alloc"))]
267+
mod alloc {
268+
pub use core::iter::Iterator;
269+
pub type Box<X> = ::core::marker::PhantomData<X>;
270+
pub use core::result::Result;
271+
272+
pub trait Error {
273+
fn description(&self) -> &str;
274+
275+
fn cause(&self) -> Option<&Error>;
276+
}
277+
}
278+
// For use in the expanded macro.
279+
#[doc(hidden)]
280+
pub use alloc::*;
261281

262282
#[cfg(feature = "backtrace")]
263283
pub use backtrace::Backtrace;
@@ -273,12 +293,12 @@ mod error_chain;
273293
pub mod example_generated;
274294

275295
/// Iterator over the error chain using the `Error::cause()` method.
276-
pub struct ErrorChainIter<'a>(pub Option<&'a error::Error>);
296+
pub struct ErrorChainIter<'a>(pub Option<&'a Error>);
277297

278298
impl<'a> Iterator for ErrorChainIter<'a> {
279-
type Item = &'a error::Error;
299+
type Item = &'a Error;
280300

281-
fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
301+
fn next<'b>(&'b mut self) -> Option<&'a Error> {
282302
match self.0.take() {
283303
Some(e) => {
284304
self.0 = e.cause();
@@ -303,7 +323,7 @@ pub fn make_backtrace() -> Option<Arc<Backtrace>> {
303323

304324
/// This trait is implemented on all the errors generated by the `error_chain`
305325
/// macro.
306-
pub trait ChainedError: error::Error + Send + 'static {
326+
pub trait ChainedError: Error + Send + 'static {
307327
/// Associated kind type.
308328
type ErrorKind;
309329

@@ -315,7 +335,7 @@ pub trait ChainedError: error::Error + Send + 'static {
315335
/// of the errors from `foreign_links`.
316336
#[cfg(feature = "backtrace")]
317337
#[doc(hidden)]
318-
fn extract_backtrace(e: &(error::Error + Send + 'static))
338+
fn extract_backtrace(e: &(Error + Send + 'static))
319339
-> Option<Option<Arc<Backtrace>>>;
320340
}
321341

@@ -345,10 +365,12 @@ impl<T, E, CE> ResultExt<T, E, CE> for Result<T, E> where CE: ChainedError, E: I
345365
backtrace: backtrace,
346366
})
347367
};
348-
#[cfg(not(feature = "backtrace"))]
368+
#[cfg(all(not(feature = "backtrace"), feature = "alloc"))]
349369
let error = CE::new(callback().into(), State {
350370
next_error: Some(Box::new(e)),
351371
});
372+
#[cfg(not(feature = "alloc"))]
373+
let error = CE::new(callback().into(), State {});
352374
error
353375
})
354376
}
@@ -360,10 +382,11 @@ impl<T, E, CE> ResultExt<T, E, CE> for Result<T, E> where CE: ChainedError, E: I
360382
#[doc(hidden)]
361383
pub struct State {
362384
/// Next error in the error chain.
363-
pub next_error: Option<Box<error::Error + Send>>,
385+
#[cfg(feature = "alloc")]
386+
next_error: Option<Box<Error + Send>>,
364387
/// Backtrace for the current error.
365388
#[cfg(feature = "backtrace")]
366-
pub backtrace: Option<Arc<Backtrace>>,
389+
backtrace: Option<Arc<Backtrace>>,
367390
}
368391

369392
impl Default for State {
@@ -373,10 +396,12 @@ impl Default for State {
373396
next_error: None,
374397
backtrace: make_backtrace(),
375398
};
376-
#[cfg(not(feature = "backtrace"))]
399+
#[cfg(all(not(feature = "backtrace"), feature = "alloc"))]
377400
let state = State {
378401
next_error: None,
379402
};
403+
#[cfg(not(feature = "alloc"))]
404+
let state = State {};
380405
state
381406
}
382407
}
@@ -390,4 +415,12 @@ impl State {
390415
let b = None;
391416
b
392417
}
418+
419+
pub fn next_error(&self) -> Option<Box<Error + Send>> {
420+
#[cfg(feature = "alloc")]
421+
let next = self.next_error;
422+
#[cfg(not(feature = "alloc"))]
423+
let next = None;
424+
next
425+
}
393426
}

0 commit comments

Comments
 (0)