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

errno: io::Error to Errno conversion sugar #1155

Closed
lucab opened this issue Nov 25, 2019 · 1 comment
Closed

errno: io::Error to Errno conversion sugar #1155

lucab opened this issue Nov 25, 2019 · 1 comment

Comments

@lucab
Copy link
Contributor

lucab commented Nov 25, 2019

I'd like to have some conversion sugar to get an nix::errno::Errno from a std::io::Error. That is, going in the opposite direction of #613.

Strawman would be:

/// Convert into an `Errno`.
pub trait AsErrno {
    /// Try to convert into an `Errno`.
    ///
    /// If the conversion is not semantically meaningful, `None` is returned.
    fn as_errno(&self) -> Option<Errno>;
}

impl AsErrno for std::io::Error {
    fn as_errno(&self) -> Option<Errno> {
        self.raw_os_error().map(Errno::from_i32)
    }
}

The use case is to improve ergonomics when pattern matching on stdlib results, like this:

use nix::errno::{AsErrno, Errno};
match std::io::xyz() {
        Err(ref err) if err.as_errno() == Some(Errno::EPERM) => foo(),
       _ => bar()
}

Would something like this be welcome in nix::errno?

asomers added a commit to asomers/nix that referenced this issue Jun 13, 2021
For many of Nix's consumers it be convenient to easily convert a Nix
error into a std::io::Error.  That's currently not possible because of
the InvalidPath, InvalidUtf8, and UnsupportedOperation types that have
no equivalent in std::io::Error.

However, very few of Nix's public APIs actually return those unusual
errors.  So a more useful API would be for Nix's standard error type to
implement Into<std::io::Error>.

This commit makes Error a simple NewType around Errno.  For most
functions it's a drop-in replacement.  There are only three exceptions:

* clearenv now returns a bespoke error type.  It was the only Nix
  function whose error couldn't be cleanly mapped onto an Errno.

* sys::signal::signal now returns Error(Errno::ENOTSUP) instead of
  Error::UnsupportedOperation when the user passes an incompatible
  argument to `handler`.

* When a NixPath exceeds PATH_MAX, it will now return
  Error(Errno::ENAMETOOLONG) instead of Error::InvalidPath.

In the latter two cases there is now some abiguity about whether the
error code was generated by Nix or by the OS.  But I think the ambiguity
is worth it for the sake of being able to implement Into<io::Error>.

This commit also introduces Error::Sys() as a migration aid.  Previously
that as an enum variant.  Now it's a function, but it will work in many
of the same contexts as the original.

Fixes nix-rust#1155
asomers added a commit to asomers/nix that referenced this issue Jun 13, 2021
For many of Nix's consumers it be convenient to easily convert a Nix
error into a std::io::Error.  That's currently not possible because of
the InvalidPath, InvalidUtf8, and UnsupportedOperation types that have
no equivalent in std::io::Error.

However, very few of Nix's public APIs actually return those unusual
errors.  So a more useful API would be for Nix's standard error type to
implement Into<std::io::Error>.

This commit makes Error a simple NewType around Errno.  For most
functions it's a drop-in replacement.  There are only three exceptions:

* clearenv now returns a bespoke error type.  It was the only Nix
  function whose error couldn't be cleanly mapped onto an Errno.

* sys::signal::signal now returns Error(Errno::ENOTSUP) instead of
  Error::UnsupportedOperation when the user passes an incompatible
  argument to `handler`.

* When a NixPath exceeds PATH_MAX, it will now return
  Error(Errno::ENAMETOOLONG) instead of Error::InvalidPath.

In the latter two cases there is now some abiguity about whether the
error code was generated by Nix or by the OS.  But I think the ambiguity
is worth it for the sake of being able to implement Into<io::Error>.

This commit also introduces Error::Sys() as a migration aid.  Previously
that as an enum variant.  Now it's a function, but it will work in many
of the same contexts as the original.

Fixes nix-rust#1155
@bors bors bot closed this as completed in 6511d02 Jul 8, 2021
@lucab
Copy link
Contributor Author

lucab commented Jul 8, 2021

Thanks @asomers! 💚

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant