pub enum Outcome<T, E> {
Ok(T),
Err(E),
Cancelled(CancelReason),
Panicked(PanicPayload),
}Expand description
The four-valued outcome of a concurrent operation.
Forms a severity lattice where worse outcomes dominate:
Ok < Err < Cancelled < Panicked
Variants§
Ok(T)
Success with a value.
Err(E)
Application-level error.
Cancelled(CancelReason)
The operation was cancelled.
Panicked(PanicPayload)
The operation panicked.
Implementations§
Source§impl<T> Outcome<T, AtpError>
Convenience constructors for ATP outcomes.
impl<T> Outcome<T, AtpError>
Convenience constructors for ATP outcomes.
Sourcepub fn transport_error(error: TransportError) -> Outcome<T, AtpError>
pub fn transport_error(error: TransportError) -> Outcome<T, AtpError>
Create a transport error outcome.
Sourcepub fn protocol_error(error: ProtocolError) -> Outcome<T, AtpError>
pub fn protocol_error(error: ProtocolError) -> Outcome<T, AtpError>
Create a protocol error outcome.
Sourcepub fn auth_error(error: AuthError) -> Outcome<T, AtpError>
pub fn auth_error(error: AuthError) -> Outcome<T, AtpError>
Create an auth error outcome.
Sourcepub fn disk_error(error: DiskError) -> Outcome<T, AtpError>
pub fn disk_error(error: DiskError) -> Outcome<T, AtpError>
Create a disk error outcome.
Sourcepub fn atp_cancelled(reason: AtpCancelReason) -> Outcome<T, AtpError>
pub fn atp_cancelled(reason: AtpCancelReason) -> Outcome<T, AtpError>
Create an ATP cancellation outcome.
Source§impl<T, E> Outcome<T, E>
impl<T, E> Outcome<T, E>
Sourcepub const fn ok(value: T) -> Outcome<T, E>
pub const fn ok(value: T) -> Outcome<T, E>
Creates a successful outcome with the given value.
§Examples
use asupersync::Outcome;
let outcome: Outcome<i32, &str> = Outcome::ok(42);
assert!(outcome.is_ok());
assert_eq!(outcome.unwrap(), 42);Sourcepub const fn err(error: E) -> Outcome<T, E>
pub const fn err(error: E) -> Outcome<T, E>
Creates an error outcome with the given error.
§Examples
use asupersync::Outcome;
let outcome: Outcome<i32, &str> = Outcome::err("not found");
assert!(outcome.is_err());Sourcepub const fn cancelled(reason: CancelReason) -> Outcome<T, E>
pub const fn cancelled(reason: CancelReason) -> Outcome<T, E>
Creates a cancelled outcome with the given reason.
§Examples
use asupersync::{Outcome, CancelReason};
let outcome: Outcome<i32, &str> = Outcome::cancelled(CancelReason::timeout());
assert!(outcome.is_cancelled());Sourcepub const fn panicked(payload: PanicPayload) -> Outcome<T, E>
pub const fn panicked(payload: PanicPayload) -> Outcome<T, E>
Creates a panicked outcome with the given payload.
§Examples
use asupersync::{Outcome, PanicPayload};
let outcome: Outcome<i32, &str> = Outcome::panicked(PanicPayload::new("oops"));
assert!(outcome.is_panicked());Sourcepub const fn severity(&self) -> Severity
pub const fn severity(&self) -> Severity
Returns the severity level of this outcome.
The severity levels are ordered: Ok < Err < Cancelled < Panicked.
This is useful for aggregation where the worst outcome should win.
§Examples
use asupersync::{Outcome, Severity, CancelReason};
let ok: Outcome<i32, &str> = Outcome::ok(42);
let err: Outcome<i32, &str> = Outcome::err("oops");
let cancelled: Outcome<i32, &str> = Outcome::cancelled(CancelReason::timeout());
assert_eq!(ok.severity(), Severity::Ok);
assert_eq!(err.severity(), Severity::Err);
assert_eq!(cancelled.severity(), Severity::Cancelled);
assert!(ok.severity() < err.severity());Sourcepub const fn severity_u8(&self) -> u8
pub const fn severity_u8(&self) -> u8
Returns the numeric severity level (0 = Ok, 3 = Panicked).
Prefer severity() for type-safe comparisons.
Sourcepub const fn is_terminal(&self) -> bool
pub const fn is_terminal(&self) -> bool
Returns true if this is a terminal outcome (any non-pending state).
All Outcome variants are terminal states.
Sourcepub const fn is_ok(&self) -> bool
pub const fn is_ok(&self) -> bool
Returns true if this outcome is Ok.
§Examples
use asupersync::Outcome;
let ok: Outcome<i32, &str> = Outcome::ok(42);
let err: Outcome<i32, &str> = Outcome::err("oops");
assert!(ok.is_ok());
assert!(!err.is_ok());Sourcepub const fn is_err(&self) -> bool
pub const fn is_err(&self) -> bool
Returns true if this outcome is Err.
§Examples
use asupersync::Outcome;
let err: Outcome<i32, &str> = Outcome::err("oops");
assert!(err.is_err());Sourcepub const fn is_cancelled(&self) -> bool
pub const fn is_cancelled(&self) -> bool
Returns true if this outcome is Cancelled.
§Examples
use asupersync::{Outcome, CancelReason};
let cancelled: Outcome<i32, &str> = Outcome::cancelled(CancelReason::timeout());
assert!(cancelled.is_cancelled());Sourcepub const fn is_panicked(&self) -> bool
pub const fn is_panicked(&self) -> bool
Returns true if this outcome is Panicked.
§Examples
use asupersync::{Outcome, PanicPayload};
let panicked: Outcome<i32, &str> = Outcome::panicked(PanicPayload::new("oops"));
assert!(panicked.is_panicked());Sourcepub fn into_result(self) -> Result<T, OutcomeError<E>>
pub fn into_result(self) -> Result<T, OutcomeError<E>>
Converts this outcome to a standard Result, with cancellation and panic as errors.
This is useful when interfacing with code that expects Result.
Sourcepub fn map<U, F>(self, f: F) -> Outcome<U, E>where
F: FnOnce(T) -> U,
pub fn map<U, F>(self, f: F) -> Outcome<U, E>where
F: FnOnce(T) -> U,
Maps the success value using the provided function.
Sourcepub fn map_err<F2, G>(self, g: G) -> Outcome<T, F2>where
G: FnOnce(E) -> F2,
pub fn map_err<F2, G>(self, g: G) -> Outcome<T, F2>where
G: FnOnce(E) -> F2,
Maps the error value using the provided function.
§Examples
use asupersync::Outcome;
let err: Outcome<i32, &str> = Outcome::err("short");
let mapped = err.map_err(str::len);
assert!(matches!(mapped, Outcome::Err(5)));Sourcepub fn and_then<U, F>(self, f: F) -> Outcome<U, E>
pub fn and_then<U, F>(self, f: F) -> Outcome<U, E>
Applies a function to the success value, flattening the result.
This is the monadic bind operation, useful for chaining operations that might fail.
§Examples
use asupersync::Outcome;
fn parse_int(s: &str) -> Outcome<i32, &'static str> {
s.parse::<i32>().map_err(|_| "parse error").into()
}
fn double(x: i32) -> Outcome<i32, &'static str> {
Outcome::ok(x * 2)
}
let result = parse_int("21").and_then(double);
assert_eq!(result.unwrap(), 42);
let result = parse_int("abc").and_then(double);
assert!(result.is_err());Sourcepub fn ok_or_else<F2, G>(self, f: G) -> Result<T, F2>where
G: FnOnce() -> F2,
pub fn ok_or_else<F2, G>(self, f: G) -> Result<T, F2>where
G: FnOnce() -> F2,
Returns the success value, or computes a fallback from a closure.
Unlike unwrap_or_else, this returns a Result
instead of another value of T.
This intentionally collapses every non-Ok outcome (Err,
Cancelled, and Panicked) into the same lazily computed fallback
error. Use into_result if you need to preserve
which terminal outcome occurred.
§Examples
use asupersync::{Outcome, CancelReason};
let ok: Outcome<i32, &str> = Outcome::ok(42);
let result: Result<i32, &str> = ok.ok_or_else(|| "default error");
assert_eq!(result, Ok(42));
let cancelled: Outcome<i32, &str> = Outcome::cancelled(CancelReason::timeout());
let result: Result<i32, &str> = cancelled.ok_or_else(|| "was cancelled");
assert_eq!(result, Err("was cancelled"));Sourcepub fn join(self, other: Outcome<T, E>) -> Outcome<T, E>
pub fn join(self, other: Outcome<T, E>) -> Outcome<T, E>
Joins this outcome with another, returning the outcome with higher severity.
This implements the lattice join operation for aggregating outcomes from parallel tasks. The outcome with the worst (highest) severity wins.
§Note on Value Handling
When both outcomes are Ok, this method returns self. When both are
Cancelled, a strictly stronger CancelReason is retained. Equal-
severity cancellation ties remain left-biased and return self.
§Examples
use asupersync::{Outcome, CancelReason};
let ok1: Outcome<i32, &str> = Outcome::ok(1);
let ok2: Outcome<i32, &str> = Outcome::ok(2);
let err: Outcome<i32, &str> = Outcome::err("error");
let cancelled: Outcome<i32, &str> = Outcome::cancelled(CancelReason::timeout());
// Ok + Ok = first Ok (both same severity)
assert!(ok1.clone().join(ok2).is_ok());
// Ok + Err = Err (Err is worse)
assert!(ok1.clone().join(err.clone()).is_err());
// Err + Cancelled = Cancelled (Cancelled is worse)
assert!(err.join(cancelled).is_cancelled());Implements def.outcome.join_semantics (#31).
Left-bias: on equal severity, self (left argument) wins. The only
Cancelled + Cancelled special case is when the right-hand cancellation
reason has strictly higher severity and therefore strengthens the result.
This is intentional: join is associative on severity, but not fully
value-commutative. See law.join.assoc (#42).
Sourcepub fn expect(self, msg: &str) -> Twhere
E: Debug,
pub fn expect(self, msg: &str) -> Twhere
E: Debug,
Unwraps the contained Ok value, panicking with a custom message if not Ok.
Similar to Result::expect, but for Outcome.
§Examples
use asupersync::Outcome;
let outcome: Outcome<u32, &str> = Outcome::ok(42);
assert_eq!(outcome.expect("should be ok"), 42);§Panics
Panics with the provided message if the outcome is not Ok.
Sourcepub fn expect_err(self, msg: &str) -> Ewhere
T: Debug,
pub fn expect_err(self, msg: &str) -> Ewhere
T: Debug,
Unwraps the contained Err value, panicking with a custom message if not Err.
Similar to Result::expect_err, but for Outcome.
§Examples
use asupersync::Outcome;
let outcome: Outcome<u32, &str> = Outcome::err("failed");
assert_eq!(outcome.expect_err("should be error"), "failed");§Panics
Panics with the provided message if the outcome is not Err.
Sourcepub fn unwrap_or_else<F>(self, f: F) -> Twhere
F: FnOnce() -> T,
pub fn unwrap_or_else<F>(self, f: F) -> Twhere
F: FnOnce() -> T,
Returns the success value or computes it from a closure.
Trait Implementations§
Source§impl<'de, T, E> Deserialize<'de> for Outcome<T, E>where
T: Deserialize<'de>,
E: Deserialize<'de>,
impl<'de, T, E> Deserialize<'de> for Outcome<T, E>where
T: Deserialize<'de>,
E: Deserialize<'de>,
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Outcome<T, E>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Outcome<T, E>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl<T, E> Eq for Outcome<T, E>
Source§impl<T, E> FromResidual<Outcome<Infallible, E>> for Outcome<T, E>
impl<T, E> FromResidual<Outcome<Infallible, E>> for Outcome<T, E>
Source§fn from_residual(residual: Outcome<Infallible, E>) -> Outcome<T, E>
fn from_residual(residual: Outcome<Infallible, E>) -> Outcome<T, E>
try_trait_v2)Residual type. Read moreSource§impl<T, E> FromResidual<Result<Infallible, E>> for Outcome<T, E>
impl<T, E> FromResidual<Result<Infallible, E>> for Outcome<T, E>
Source§fn from_residual(residual: Result<Infallible, E>) -> Outcome<T, E>
fn from_residual(residual: Result<Infallible, E>) -> Outcome<T, E>
try_trait_v2)Residual type. Read moreSource§impl<T> OutcomeExt<T> for Outcome<T, McpError>
impl<T> OutcomeExt<T> for Outcome<T, McpError>
Source§impl<T, E> PartialEq for Outcome<T, E>
impl<T, E> PartialEq for Outcome<T, E>
Source§impl<T, E> Residual<T> for Outcome<Infallible, E>
impl<T, E> Residual<T> for Outcome<Infallible, E>
Source§impl<T, E> Serialize for Outcome<T, E>
impl<T, E> Serialize for Outcome<T, E>
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl<T, E> StructuralPartialEq for Outcome<T, E>
Source§impl<T, E> Try for Outcome<T, E>
impl<T, E> Try for Outcome<T, E>
Source§type Output = T
type Output = T
try_trait_v2)? when not short-circuiting.Source§type Residual = Outcome<Infallible, E>
type Residual = Outcome<Infallible, E>
try_trait_v2)FromResidual::from_residual
as part of ? when short-circuiting. Read moreSource§fn from_output(output: <Outcome<T, E> as Try>::Output) -> Outcome<T, E>
fn from_output(output: <Outcome<T, E> as Try>::Output) -> Outcome<T, E>
try_trait_v2)Output type. Read moreSource§fn branch(
self,
) -> ControlFlow<<Outcome<T, E> as Try>::Residual, <Outcome<T, E> as Try>::Output>
fn branch( self, ) -> ControlFlow<<Outcome<T, E> as Try>::Residual, <Outcome<T, E> as Try>::Output>
try_trait_v2)? to decide whether the operator should produce a value
(because this returned ControlFlow::Continue)
or propagate a value back to the caller
(because this returned ControlFlow::Break). Read moreAuto Trait Implementations§
impl<T, E> Freeze for Outcome<T, E>
impl<T, E> RefUnwindSafe for Outcome<T, E>where
T: RefUnwindSafe,
E: RefUnwindSafe,
impl<T, E> Send for Outcome<T, E>
impl<T, E> Sync for Outcome<T, E>
impl<T, E> Unpin for Outcome<T, E>
impl<T, E> UnsafeUnpin for Outcome<T, E>where
T: UnsafeUnpin,
E: UnsafeUnpin,
impl<T, E> UnwindSafe for Outcome<T, E>where
T: UnwindSafe,
E: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, _span: NoopSpan) -> Self
fn instrument(self, _span: NoopSpan) -> Self
Source§fn in_current_span(self) -> Self
fn in_current_span(self) -> Self
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more