Skip to main content

base_scheduler/
operation_error.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::Cancelled;
5use std::{fmt, io};
6
7/// Cooperative cancellation is distinct from an operating-system error.
8#[derive(Debug)]
9pub enum OperationError {
10    Cancelled(Cancelled),
11    Io(io::Error),
12}
13
14/// An operation's result, preserving cancellation separately from I/O failure.
15pub type OperationResult<T> = Result<T, OperationError>;
16
17impl OperationError {
18    /// I/O-compatible classification; match `Cancelled` to distinguish a cooperative request from an OS interruption.
19    pub fn kind(&self) -> io::ErrorKind {
20        match self {
21            Self::Cancelled(_) => io::ErrorKind::Interrupted,
22            Self::Io(error) => error.kind(),
23        }
24    }
25
26    pub fn raw_os_error(&self) -> Option<i32> {
27        match self {
28            Self::Cancelled(_) => None,
29            Self::Io(error) => error.raw_os_error(),
30        }
31    }
32}
33
34impl fmt::Display for OperationError {
35    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self {
37            Self::Cancelled(error) => error.fmt(formatter),
38            Self::Io(error) => error.fmt(formatter),
39        }
40    }
41}
42
43impl std::error::Error for OperationError {
44    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
45        Some(match self {
46            Self::Cancelled(error) => error,
47            Self::Io(error) => error,
48        })
49    }
50}
51
52impl From<io::Error> for OperationError {
53    fn from(error: io::Error) -> Self {
54        Self::Io(error)
55    }
56}
57
58impl From<Cancelled> for OperationError {
59    fn from(error: Cancelled) -> Self {
60        Self::Cancelled(error)
61    }
62}
63
64impl From<OperationError> for io::Error {
65    fn from(error: OperationError) -> Self {
66        match error {
67            OperationError::Io(error) => error,
68            OperationError::Cancelled(error) => Self::new(io::ErrorKind::Interrupted, error),
69        }
70    }
71}