Rename flow to result-extended
The original name has always felt awful. I understand Rust well enough now to be able to use the name Result and override the built-in Result.
This commit is contained in:
parent
27e1691854
commit
3cb742d863
|
@ -861,13 +861,6 @@ dependencies = [
|
|||
"miniz_oxide 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flow"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent"
|
||||
version = "0.16.0"
|
||||
|
@ -3119,6 +3112,13 @@ dependencies = [
|
|||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "result-extended"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.2"
|
||||
|
|
|
@ -8,7 +8,6 @@ members = [
|
|||
"dashboard",
|
||||
"emseries",
|
||||
"file-service",
|
||||
"flow",
|
||||
"fluent-ergonomics",
|
||||
"geo-types",
|
||||
"gm-control-panel",
|
||||
|
@ -17,7 +16,8 @@ members = [
|
|||
"kifu/core",
|
||||
"kifu/gtk",
|
||||
"memorycache",
|
||||
"nom-training",
|
||||
"result-extended",
|
||||
"screenplay",
|
||||
"sgf",
|
||||
"nom-training",
|
||||
]
|
||||
|
|
3
build.sh
3
build.sh
|
@ -11,7 +11,6 @@ RUST_ALL_TARGETS=(
|
|||
"dashboard"
|
||||
"emseries"
|
||||
"file-service"
|
||||
"flow"
|
||||
"fluent-ergonomics"
|
||||
"geo-types"
|
||||
"gm-control-panel"
|
||||
|
@ -20,6 +19,8 @@ RUST_ALL_TARGETS=(
|
|||
"kifu-core"
|
||||
"kifu-gtk"
|
||||
"memorycache"
|
||||
"nom-training"
|
||||
"result-extended"
|
||||
"screenplay"
|
||||
"sgf"
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "flow"
|
||||
name = "result-extended"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-only"
|
|
@ -33,9 +33,9 @@ use std::{error::Error, fmt};
|
|||
/// statement.
|
||||
pub trait FatalError: Error {}
|
||||
|
||||
/// Flow<A, FE, E> represents a return value that might be a success, might be a fatal error, or
|
||||
/// Result<A, FE, E> represents a return value that might be a success, might be a fatal error, or
|
||||
/// might be a normal handleable error.
|
||||
pub enum Flow<A, FE, E> {
|
||||
pub enum Result<A, FE, E> {
|
||||
/// The operation was successful
|
||||
Ok(A),
|
||||
/// The operation encountered a fatal error. These should be bubbled up to a level that can
|
||||
|
@ -45,72 +45,72 @@ pub enum Flow<A, FE, E> {
|
|||
Err(E),
|
||||
}
|
||||
|
||||
impl<A, FE, E> Flow<A, FE, E> {
|
||||
impl<A, FE, E> Result<A, FE, E> {
|
||||
/// Apply an infallible function to a successful value.
|
||||
pub fn map<B, O>(self, mapper: O) -> Flow<B, FE, E>
|
||||
pub fn map<B, O>(self, mapper: O) -> Result<B, FE, E>
|
||||
where
|
||||
O: FnOnce(A) -> B,
|
||||
{
|
||||
match self {
|
||||
Flow::Ok(val) => Flow::Ok(mapper(val)),
|
||||
Flow::Fatal(err) => Flow::Fatal(err),
|
||||
Flow::Err(err) => Flow::Err(err),
|
||||
Result::Ok(val) => Result::Ok(mapper(val)),
|
||||
Result::Fatal(err) => Result::Fatal(err),
|
||||
Result::Err(err) => Result::Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply a potentially fallible function to a successful value.
|
||||
///
|
||||
/// Like `Result.and_then`, the mapping function can itself fail.
|
||||
pub fn and_then<B, O>(self, handler: O) -> Flow<B, FE, E>
|
||||
pub fn and_then<B, O>(self, handler: O) -> Result<B, FE, E>
|
||||
where
|
||||
O: FnOnce(A) -> Flow<B, FE, E>,
|
||||
O: FnOnce(A) -> Result<B, FE, E>,
|
||||
{
|
||||
match self {
|
||||
Flow::Ok(val) => handler(val),
|
||||
Flow::Fatal(err) => Flow::Fatal(err),
|
||||
Flow::Err(err) => Flow::Err(err),
|
||||
Result::Ok(val) => handler(val),
|
||||
Result::Fatal(err) => Result::Fatal(err),
|
||||
Result::Err(err) => Result::Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Map a normal error from one type to another. This is useful for converting an error from
|
||||
/// one type to another, especially in re-throwing an underlying error. `?` syntax does not
|
||||
/// work with `Flow`, so you will likely need to use this a lot.
|
||||
pub fn map_err<F, O>(self, mapper: O) -> Flow<A, FE, F>
|
||||
/// work with `Result`, so you will likely need to use this a lot.
|
||||
pub fn map_err<F, O>(self, mapper: O) -> Result<A, FE, F>
|
||||
where
|
||||
O: FnOnce(E) -> F,
|
||||
{
|
||||
match self {
|
||||
Flow::Ok(val) => Flow::Ok(val),
|
||||
Flow::Fatal(err) => Flow::Fatal(err),
|
||||
Flow::Err(err) => Flow::Err(mapper(err)),
|
||||
Result::Ok(val) => Result::Ok(val),
|
||||
Result::Fatal(err) => Result::Fatal(err),
|
||||
Result::Err(err) => Result::Err(mapper(err)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide a function to use to recover from (or simply re-throw) an error.
|
||||
pub fn or_else<O, F>(self, handler: O) -> Flow<A, FE, F>
|
||||
pub fn or_else<O, F>(self, handler: O) -> Result<A, FE, F>
|
||||
where
|
||||
O: FnOnce(E) -> Flow<A, FE, F>,
|
||||
O: FnOnce(E) -> Result<A, FE, F>,
|
||||
{
|
||||
match self {
|
||||
Flow::Ok(val) => Flow::Ok(val),
|
||||
Flow::Fatal(err) => Flow::Fatal(err),
|
||||
Flow::Err(err) => handler(err),
|
||||
Result::Ok(val) => Result::Ok(val),
|
||||
Result::Fatal(err) => Result::Fatal(err),
|
||||
Result::Err(err) => handler(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from a normal `Result` type to a `Flow` type. The error condition for a `Result` will
|
||||
/// be treated as `Flow::Err`, never `Flow::Fatal`.
|
||||
impl<A, FE, E> From<Result<A, E>> for Flow<A, FE, E> {
|
||||
fn from(r: Result<A, E>) -> Self {
|
||||
/// Convert from a normal `Result` type to a `Result` type. The error condition for a `Result` will
|
||||
/// be treated as `Result::Err`, never `Result::Fatal`.
|
||||
impl<A, FE, E> From<std::result::Result<A, E>> for Result<A, FE, E> {
|
||||
fn from(r: std::result::Result<A, E>) -> Self {
|
||||
match r {
|
||||
Ok(val) => Flow::Ok(val),
|
||||
Err(err) => Flow::Err(err),
|
||||
Ok(val) => Result::Ok(val),
|
||||
Err(err) => Result::Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, FE, E> fmt::Debug for Flow<A, FE, E>
|
||||
impl<A, FE, E> fmt::Debug for Result<A, FE, E>
|
||||
where
|
||||
A: fmt::Debug,
|
||||
FE: fmt::Debug,
|
||||
|
@ -118,14 +118,14 @@ where
|
|||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Flow::Ok(val) => f.write_fmt(format_args!("Flow::Ok {:?}", val)),
|
||||
Flow::Err(err) => f.write_fmt(format_args!("Flow::Err {:?}", err)),
|
||||
Flow::Fatal(err) => f.write_fmt(format_args!("Flow::Fatal {:?}", err)),
|
||||
Result::Ok(val) => f.write_fmt(format_args!("Result::Ok {:?}", val)),
|
||||
Result::Err(err) => f.write_fmt(format_args!("Result::Err {:?}", err)),
|
||||
Result::Fatal(err) => f.write_fmt(format_args!("Result::Fatal {:?}", err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, FE, E> PartialEq for Flow<A, FE, E>
|
||||
impl<A, FE, E> PartialEq for Result<A, FE, E>
|
||||
where
|
||||
A: PartialEq,
|
||||
FE: PartialEq,
|
||||
|
@ -133,27 +133,27 @@ where
|
|||
{
|
||||
fn eq(&self, rhs: &Self) -> bool {
|
||||
match (self, rhs) {
|
||||
(Flow::Ok(val), Flow::Ok(rhs)) => val == rhs,
|
||||
(Flow::Err(_), Flow::Err(_)) => true,
|
||||
(Flow::Fatal(_), Flow::Fatal(_)) => true,
|
||||
(Result::Ok(val), Result::Ok(rhs)) => val == rhs,
|
||||
(Result::Err(_), Result::Err(_)) => true,
|
||||
(Result::Fatal(_), Result::Fatal(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience function to create an ok value.
|
||||
pub fn ok<A, FE: FatalError, E: Error>(val: A) -> Flow<A, FE, E> {
|
||||
Flow::Ok(val)
|
||||
pub fn ok<A, FE: FatalError, E: Error>(val: A) -> Result<A, FE, E> {
|
||||
Result::Ok(val)
|
||||
}
|
||||
|
||||
/// Convenience function to create an error value.
|
||||
pub fn error<A, FE: FatalError, E: Error>(err: E) -> Flow<A, FE, E> {
|
||||
Flow::Err(err)
|
||||
pub fn error<A, FE: FatalError, E: Error>(err: E) -> Result<A, FE, E> {
|
||||
Result::Err(err)
|
||||
}
|
||||
|
||||
/// Convenience function to create a fatal value.
|
||||
pub fn fatal<A, FE: FatalError, E: Error>(err: FE) -> Flow<A, FE, E> {
|
||||
Flow::Fatal(err)
|
||||
pub fn fatal<A, FE: FatalError, E: Error>(err: FE) -> Result<A, FE, E> {
|
||||
Result::Fatal(err)
|
||||
}
|
||||
|
||||
/// Return early from the current function if the value is a fatal error.
|
||||
|
@ -161,9 +161,9 @@ pub fn fatal<A, FE: FatalError, E: Error>(err: FE) -> Flow<A, FE, E> {
|
|||
macro_rules! return_fatal {
|
||||
($x:expr) => {
|
||||
match $x {
|
||||
Flow::Fatal(err) => return Flow::Fatal(err),
|
||||
Flow::Err(err) => Err(err),
|
||||
Flow::Ok(val) => Ok(val),
|
||||
Result::Fatal(err) => return Result::Fatal(err),
|
||||
Result::Err(err) => Err(err),
|
||||
Result::Ok(val) => Ok(val),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -173,9 +173,9 @@ macro_rules! return_fatal {
|
|||
macro_rules! return_error {
|
||||
($x:expr) => {
|
||||
match $x {
|
||||
Flow::Ok(val) => val,
|
||||
Flow::Err(err) => return Flow::Err(err),
|
||||
Flow::Fatal(err) => return Flow::Fatal(err),
|
||||
Result::Ok(val) => val,
|
||||
Result::Err(err) => return Result::Err(err),
|
||||
Result::Fatal(err) => return Result::Fatal(err),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -210,19 +210,19 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn it_can_map_things() {
|
||||
let success: Flow<i32, FatalError, Error> = ok(15);
|
||||
let success: Result<i32, FatalError, Error> = ok(15);
|
||||
assert_eq!(ok(16), success.map(|v| v + 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_chain_success() {
|
||||
let success: Flow<i32, FatalError, Error> = ok(15);
|
||||
let success: Result<i32, FatalError, Error> = ok(15);
|
||||
assert_eq!(ok(16), success.and_then(|v| ok(v + 1)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_handle_an_error() {
|
||||
let failure: Flow<i32, FatalError, Error> = error(Error::Error);
|
||||
let failure: Result<i32, FatalError, Error> = error(Error::Error);
|
||||
assert_eq!(
|
||||
ok::<i32, FatalError, Error>(16),
|
||||
failure.or_else(|_| ok(16))
|
||||
|
@ -231,7 +231,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn early_exit_on_fatal() {
|
||||
fn ok_func() -> Flow<i32, FatalError, Error> {
|
||||
fn ok_func() -> Result<i32, FatalError, Error> {
|
||||
let value = return_fatal!(ok::<i32, FatalError, Error>(15));
|
||||
match value {
|
||||
Ok(_) => ok(14),
|
||||
|
@ -239,7 +239,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
fn err_func() -> Flow<i32, FatalError, Error> {
|
||||
fn err_func() -> Result<i32, FatalError, Error> {
|
||||
let value = return_fatal!(error::<i32, FatalError, Error>(Error::Error));
|
||||
match value {
|
||||
Ok(_) => panic!("shouldn't have gotten here"),
|
||||
|
@ -247,7 +247,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
fn fatal_func() -> Flow<i32, FatalError, Error> {
|
||||
fn fatal_func() -> Result<i32, FatalError, Error> {
|
||||
return_fatal!(fatal::<i32, FatalError, Error>(FatalError::FatalError));
|
||||
panic!("failed to bail");
|
||||
}
|
||||
|
@ -259,18 +259,18 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn it_can_early_exit_on_all_errors() {
|
||||
fn ok_func() -> Flow<i32, FatalError, Error> {
|
||||
fn ok_func() -> Result<i32, FatalError, Error> {
|
||||
let value = return_error!(ok::<i32, FatalError, Error>(15));
|
||||
assert_eq!(value, 15);
|
||||
ok(14)
|
||||
}
|
||||
|
||||
fn err_func() -> Flow<i32, FatalError, Error> {
|
||||
fn err_func() -> Result<i32, FatalError, Error> {
|
||||
return_error!(error::<i32, FatalError, Error>(Error::Error));
|
||||
panic!("failed to bail");
|
||||
}
|
||||
|
||||
fn fatal_func() -> Flow<i32, FatalError, Error> {
|
||||
fn fatal_func() -> Result<i32, FatalError, Error> {
|
||||
return_error!(fatal::<i32, FatalError, Error>(FatalError::FatalError));
|
||||
panic!("failed to bail");
|
||||
}
|
Loading…
Reference in New Issue