cancel_this/
error.rs

1use std::fmt::{Debug, Display, Formatter};
2
3/// Cancellation error type. Should include the cause of cancellation (name of the
4/// [`crate::CancellationTrigger`] type that caused the error).
5///
6/// In cases where the operation itself can result in an error `E`, make sure to implement
7/// `From<Cancelled>` for `E`, meaning you'll still be able to use
8/// the `is_cancelled` macro and other features of this crate.
9#[derive(Clone, Debug, PartialEq, Eq, Hash)]
10pub struct Cancelled {
11    cause: &'static str,
12}
13
14/// A result of a cancellable operation.
15pub type Cancellable<TResult> = Result<TResult, Cancelled>;
16
17impl Cancelled {
18    /// Create a new [`Cancelled`] with a cause type.
19    pub fn new(cause: &'static str) -> Self {
20        Cancelled { cause }
21    }
22}
23
24impl Display for Cancelled {
25    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26        write!(f, "Operation cancelled (caused by `{}`)", self.cause)
27    }
28}
29
30impl std::error::Error for Cancelled {}
31
32impl Default for Cancelled {
33    fn default() -> Self {
34        Cancelled::new(crate::UNKNOWN_CAUSE)
35    }
36}
37
38impl Cancelled {
39    /// The name of the [`crate::CancellationTrigger`] that caused the error. If the cause is unknown,
40    /// use [`crate::UNKNOWN_CAUSE`].
41    pub fn cause(&self) -> &'static str {
42        self.cause
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::Cancelled;
49
50    #[test]
51    fn test_cancelled_error() {
52        let cancelled = Cancelled::new("CancelAtomic");
53        assert_eq!(cancelled.cause(), "CancelAtomic");
54        assert_eq!(
55            cancelled.to_string(),
56            "Operation cancelled (caused by `CancelAtomic`)"
57        );
58        let default = Cancelled::default();
59        assert_eq!(default.cause(), crate::UNKNOWN_CAUSE);
60        assert_eq!(
61            default.to_string(),
62            "Operation cancelled (caused by `UnknownCancellationTrigger`)"
63        );
64    }
65}