Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can we better support no-std usecases? #85

Closed
shepmaster opened this issue May 18, 2019 · 10 comments · Fixed by #138
Closed

How can we better support no-std usecases? #85

shepmaster opened this issue May 18, 2019 · 10 comments · Fixed by #138
Labels
enhancement New feature or request feedback requested User feedback desired on a design decision

Comments

@shepmaster
Copy link
Owner

Originally, SNAFU was going to support no-std, until I learned that the Error trait doesn't exist in libcore!

That being said, people have said that failure works will in no-std. Evidently, failure can just implement Display in this case.

We certainly could do the same, but I wonder if there's some other powers we could add. My wildest thought would be to establish a parallel Error trait that we could implement instead of (or in addition to?) std::error::Error.

Would this be something that ErrorCompat should do?

@shepmaster shepmaster added enhancement New feature or request help wanted Extra attention is needed feedback requested User feedback desired on a design decision labels May 18, 2019
@lnicola
Copy link

lnicola commented May 21, 2019

I think sticking a #[cfg(feature = "std")] on the impl will be enough for now. It's not very clear what benefits adding a new trait will have, especially without buy-in from the ecosystem.

@shepmaster
Copy link
Owner Author

I think sticking a #[cfg(feature = "std")] on the impl will be enough for now.

Without implementing error::Error, what benefits would people get from SNAFU? I'm not arguing, I just don't fully understand it yet.

@lnicola
Copy link

lnicola commented May 21, 2019

An error enum with conversions, possibly backtrackes (?) and optional no_std compat, I guess.

@shepmaster
Copy link
Owner Author

shepmaster commented May 21, 2019

I guess.

Are you interested in using SNAFU in a no-std environment? If so, which aspects are you looking for?

backtrackes

I don't think this is possible as Backtrace appears to require std.

optional no_std compat

Isn't that what we are talking about? To put it another way, every crate could have a no-std mode. In the worst case, everything in the crate would be disabled. I hope you'd agree that such a switch would not be useful, however.

That's what I'm trying to determine — what is the usefulness of SNAFU when it doesn't have access to the standard library?

@lnicola
Copy link

lnicola commented May 21, 2019

Are you interested in using SNAFU in a no-std environment? If so, which aspects are you looking for?

No, not right now. I've published an optional no-std crate, but I used a hand-written enum for it. I didn't consider snafu when I've written it.

I don't think this is possible as Backtrace appears to require std.

Ah, okay. I was on my phone and couldn't check.

Isn't that what we are talking about? To put it another way, every crate could have a no-std mode. In the worst case, everything in the crate would be disabled.

The crate I mentioned earlier has optional std support for two things:

  • `serde/std
  • implementing std::error::Error on its error type

what is the usefulness of SNAFU when it doesn't have access to the standard library?

Having the conversions might be enough for some. If people are using failure, they could probably use snafu if that Error impl was feature-gated.

@shepmaster
Copy link
Owner Author

I used a hand-written enum for it

What interface does that enum present to the user who consumes it? How do they make use of an error type that doesn't implement Error? Do they just use the Display implementation?

Having the conversions might be enough for some.

This is a benefit to the library author, certainly, and I can see how it might be nice.

If people are using failure, they could probably use snafu

Sure, which is why I opened this issue in the first place, but I don't yet understand the benefits of using either Failure or SNAFU in a no-std crate.

@shepmaster
Copy link
Owner Author

Thank you for this conversation, by the way!

@silwol
Copy link
Contributor

silwol commented Jun 27, 2019

As somebody who recently started migrating from failure to snafu, I would like to express my interest in no-std support as well. One of my use cases is to have a crate which contains definitions of several different enums that are used in a protocol for communication between a host computer and a microcontroller connected by USB. These for example implement TryFrom<u8> for mapping bytes of the communication stream to the enum variants. It would be helpful if I could use these implementations in the microcontroller firmware.
I recently really started to enjoy the convenience I get from using snafu in terms of ease of use (ensure!() macro, .context() method etc.) and would love to use these items in the microcontroller firmware implementation.
My current options are to either duplicate some implementation details (e.g. an alternative implementation of TryFrom behind a feature flag), to migrate away from snafu now that I really started to like the convenience, or to duplicate the whole enum definitions, leading to an increased effort in keeping this synchronized. I would really love to see no-std support for snafu (without backtrace support in this case, so I would put the backtrace fields of my error variants behind a feature flag).

@shepmaster
Copy link
Owner Author

I’m open to having this happen. As I understand it, the plan basically needs to be:

  1. Find all usages of std:: in snafu-derive and replace them with core:: equivalents.
  2. For the ones that have no equivalent (hopefully just std::error::Error), provide no-op replacements via if cfg!(feature = "std”) (see existing examples for backtraces).
  3. Define that feature flag in snafu-derive and snafu. It should be optional and off-by-default in snafu-derive and optional and on-by-default in snafu. snafu should enable the feature in snafu-derive.
  4. The hardest part IMO is writing a test for this. I have yet to figure out how to write a no-std test other than by grepping the rlib’s symbols for std which is exceedingly brittle.

@roblabla
Copy link

roblabla commented Jul 30, 2019

FWIW: backtrace-rs could in theory be no_std and in fact std is an optional feature, although I suspect all current backends require std (maybe the goblin/addr2line backend doesn't ?)

I am personally working on a project (custom OS) that will eventually involve a no_std backtrace implementation. At that point, snafu will make a lot of sense for me for error handling as it provides:

  • A very ergonomic way to transform errors through the context system
  • "Automagic" backtrace support

CryZe added a commit to CryZe/snafu that referenced this issue Aug 6, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Aug 7, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Aug 7, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Aug 16, 2019
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 shepmaster#85
@shepmaster shepmaster pinned this issue Aug 27, 2019
CryZe added a commit to CryZe/snafu that referenced this issue Aug 29, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Sep 25, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Sep 25, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Sep 30, 2019
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 shepmaster#85
CryZe added a commit to CryZe/snafu that referenced this issue Oct 1, 2019
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 shepmaster#85
shepmaster pushed a commit to CryZe/snafu that referenced this issue Oct 8, 2019
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.

In order to not commit to having a publicly visible copy of the
`Error` trait in SNAFU, hiding it from the documentation allows for
SNAFU to still support all of its features, but the user never gets to
use the trait. This way SNAFU can switch out the trait at any point
with `core::error::Error` if that becomes a thing. Alternatively the
trait here can also be made visible at some point. Both of these
possibilities are not breaking, so the conservative approach with
`doc(hidden)` allows for the smoothest experience going forward.

Resolves shepmaster#85
@shepmaster shepmaster unpinned this issue Nov 8, 2019
@shepmaster shepmaster removed the help wanted Extra attention is needed label Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feedback requested User feedback desired on a design decision
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants