Option type which short-cirtuits on Some instead of None in Try contexts
This commit is contained in:
parent
b22254cb32
commit
b3d4159883
|
|
@ -7,6 +7,7 @@ edition = "2024"
|
||||||
default = ["alloc"]
|
default = ["alloc"]
|
||||||
alloc = []
|
alloc = []
|
||||||
std = ["alloc"]
|
std = ["alloc"]
|
||||||
|
transposed-option = ["nightly"]
|
||||||
nightly = []
|
nightly = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![cfg_attr(feature = "nightly", feature(strict_provenance_atomic_ptr))]
|
#![cfg_attr(feature = "nightly", feature(strict_provenance_atomic_ptr))]
|
||||||
|
#![cfg_attr(feature = "transposed-option", feature(try_trait_v2))]
|
||||||
|
|
||||||
#[cfg(any(test, feature = "std", feature = "alloc"))]
|
#[cfg(any(test, feature = "std", feature = "alloc"))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
@ -10,6 +11,8 @@ extern crate std;
|
||||||
pub mod atomic;
|
pub mod atomic;
|
||||||
pub mod cachepadded;
|
pub mod cachepadded;
|
||||||
pub mod drop_guard;
|
pub mod drop_guard;
|
||||||
|
#[cfg(feature = "transposed-option")]
|
||||||
|
pub mod option;
|
||||||
pub mod ptr;
|
pub mod ptr;
|
||||||
pub mod rand;
|
pub mod rand;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
|
|
||||||
98
src/option.rs
Normal file
98
src/option.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
|
||||||
|
pub enum TransposedOption<T> {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Some(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> TransposedOption<T> {
|
||||||
|
pub fn new(value: T) -> Self {
|
||||||
|
TransposedOption::Some(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_none(&self) -> bool {
|
||||||
|
matches!(self, TransposedOption::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map<U, F>(self, f: F) -> TransposedOption<U>
|
||||||
|
where
|
||||||
|
F: FnOnce(T) -> U,
|
||||||
|
{
|
||||||
|
use TransposedOption::*;
|
||||||
|
match self {
|
||||||
|
Some(value) => Some(f(value)),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn and_then<U, F>(self, f: F) -> TransposedOption<U>
|
||||||
|
where
|
||||||
|
F: FnOnce(T) -> TransposedOption<U>,
|
||||||
|
{
|
||||||
|
use TransposedOption::*;
|
||||||
|
match self {
|
||||||
|
Some(value) => f(value),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Option<T>> for TransposedOption<T> {
|
||||||
|
fn from(option: Option<T>) -> Self {
|
||||||
|
match option {
|
||||||
|
Some(value) => TransposedOption::Some(value),
|
||||||
|
None => TransposedOption::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<TransposedOption<T>> for Option<T> {
|
||||||
|
fn from(transposed: TransposedOption<T>) -> Self {
|
||||||
|
match transposed {
|
||||||
|
TransposedOption::Some(value) => Some(value),
|
||||||
|
TransposedOption::None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> core::ops::Try for TransposedOption<T> {
|
||||||
|
type Output = TransposedOption<T>;
|
||||||
|
type Residual = T;
|
||||||
|
|
||||||
|
fn from_output(_: Self::Output) -> Self {
|
||||||
|
use TransposedOption::*;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn branch(self) -> std::ops::ControlFlow<Self::Residual, Self::Output> {
|
||||||
|
use TransposedOption::*;
|
||||||
|
match self {
|
||||||
|
Some(value) => std::ops::ControlFlow::Break(value),
|
||||||
|
None => std::ops::ControlFlow::Continue(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: From<U>, U> core::ops::FromResidual<U> for TransposedOption<T> {
|
||||||
|
fn from_residual(residual: U) -> Self {
|
||||||
|
Self::new(residual.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use TransposedOption::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transposed_option_try() {
|
||||||
|
let a: TransposedOption<i32> = try {
|
||||||
|
TransposedOption::Some(42)?;
|
||||||
|
None::<i32>?;
|
||||||
|
|
||||||
|
Some(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(a, TransposedOption::Some(42));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue