diff options
Diffstat (limited to 'third_party/rust/void')
-rw-r--r-- | third_party/rust/void/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/void/Cargo.toml | 15 | ||||
-rw-r--r-- | third_party/rust/void/README.md | 39 | ||||
-rw-r--r-- | third_party/rust/void/src/lib.rs | 121 |
4 files changed, 176 insertions, 0 deletions
diff --git a/third_party/rust/void/.cargo-checksum.json b/third_party/rust/void/.cargo-checksum.json new file mode 100644 index 0000000000..9554bcd9d7 --- /dev/null +++ b/third_party/rust/void/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"ea686f87a150a8e43c4b7db57c56d3eda2a4963420d5570d91d99d7d610dd3fb","README.md":"f85783a6fcf9ecc19edabd710775a88430d9e886f46728bfd7d65cef55ff3e73","src/lib.rs":"7ab8269f30715c0729b0e04e5a09be4c413664dc4b530746ea3240ac80a64c66"},"package":"6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"}
\ No newline at end of file diff --git a/third_party/rust/void/Cargo.toml b/third_party/rust/void/Cargo.toml new file mode 100644 index 0000000000..1a031396ab --- /dev/null +++ b/third_party/rust/void/Cargo.toml @@ -0,0 +1,15 @@ +[package] + +name = "void" +version = "1.0.2" +authors = ["Jonathan Reem <jonathan.reem@gmail.com>"] +repository = "https://github.com/reem/rust-void.git" +description = "The uninhabited void type for use in statically impossible cases." +readme = "README.md" +license = "MIT" + +[features] + +default = ["std"] +std = [] + diff --git a/third_party/rust/void/README.md b/third_party/rust/void/README.md new file mode 100644 index 0000000000..4f86c21cca --- /dev/null +++ b/third_party/rust/void/README.md @@ -0,0 +1,39 @@ +# Void + +> The uninhabited void type for use in statically impossible cases. + +## [Documentation](https://crates.fyi/crates/void/1.0.1) + +The uninhabited type, `enum Void { }` is useful in dealing with cases you +know to be impossible. For instance, if you are implementing a trait which +allows for error checking, but your case always succeeds, you can mark the +error case or type as `Void`, signaling to the compiler it can never happen. + +This crate also comes packed with a few traits offering extension methods to +`Result<T, Void>` and `Result<Void, T>`. + +## Usage + +Use the crates.io repository; add this to your `Cargo.toml` along +with the rest of your dependencies: + +```toml +[dependencies] +void = "1" +``` + +Then, use `Void` in your crate: + +```rust +extern crate void; +use void::Void; +``` + +## Author + +[Jonathan Reem](https://medium.com/@jreem) is the primary author and maintainer of void. + +## License + +MIT + diff --git a/third_party/rust/void/src/lib.rs b/third_party/rust/void/src/lib.rs new file mode 100644 index 0000000000..3b6287c1b2 --- /dev/null +++ b/third_party/rust/void/src/lib.rs @@ -0,0 +1,121 @@ +#![cfg_attr(test, deny(warnings))] +#![deny(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] + +//! # Void +//! +//! The uninhabited void type for use in statically impossible cases. +//! +//! In its own crate so all the users in the ecosystem can share the same type. +//! This crate also comes ready with several extension traits for Result that add +//! extra functionality to `Result<T, Void>` and `Result<Void, E>`. +//! + +#[cfg(not(feature = "std"))] +mod coreprovider { + extern crate core; + pub use core::{fmt, cmp}; +} + +#[cfg(feature = "std")] +mod coreprovider { + pub use std::{fmt, cmp, error}; +} + +use coreprovider::*; + +/// The empty type for cases which can't occur. +#[derive(Copy)] +pub enum Void { } + +impl Clone for Void { + fn clone(&self) -> Void { + unreachable(*self) + } +} + +impl fmt::Debug for Void { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unreachable(*self) + } +} + +impl fmt::Display for Void { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unreachable(*self) + } +} + +impl<T> cmp::PartialEq<T> for Void { + fn eq(&self, _: &T) -> bool { + unreachable(*self) + } +} + +impl<T> cmp::PartialOrd<T> for Void { + fn partial_cmp(&self, _: &T) -> Option<cmp::Ordering> { + unreachable(*self) + } +} + +#[cfg(feature = "std")] +impl error::Error for Void { + fn description(&self) -> &str { + unreachable(*self) + } + + fn cause(&self) -> Option<&error::Error> { + unreachable(*self) + } +} + +/// A safe version of `intrinsincs::unreachable`. +/// +/// If this typechecks, anything that causes this to run is unreachable code. +/// +/// Calling this function in reachable code invokes undefined behavior, but +/// should not be possible unless `unsafe` was used elsewhere to construct +/// an instance of `Void` (which is already undefined behavior). +#[inline(always)] +pub fn unreachable(x: Void) -> ! { + match x {} +} + +/// Extensions to `Result<T, Void>` +pub trait ResultVoidExt<T>: Sized { + /// Get the value out of a wrapper. + fn void_unwrap(self) -> T; +} + +impl<T> ResultVoidExt<T> for Result<T, Void> { + /// Get the value out of an always-ok Result. + /// + /// Never panics, since it is statically known to be Ok. + #[inline] + fn void_unwrap(self) -> T { + match self { + Ok(val) => val, + Err(e) => unreachable(e) + } + } +} + +/// Extensions to `Result<Void, E>` +pub trait ResultVoidErrExt<E>: Sized { + /// Get the error out of a wrapper. + fn void_unwrap_err(self) -> E; +} + +impl<E> ResultVoidErrExt<E> for Result<Void, E> { + /// Get the error out of an always-err Result. + /// + /// Never panics, since it is statically known to be Err. + #[inline] + fn void_unwrap_err(self) -> E { + match self { + Ok(v) => unreachable(v), + Err(e) => e + } + } +} + |