1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#[cfg(has_not_matches)]
#[macro_export]
macro_rules! my_matches {
    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
        match $expression {
            $( $pattern )|+ $( if $guard )? => true,
            _ => false
        }
    }
}
#[cfg(not(has_not_matches))]
#[macro_export]
macro_rules! my_matches {
    ($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
        matches!($expression, $( $pattern )|+ $( if $guard )?)
    }
}

pub trait BrokenPipeError {
    fn is_broken_pipe(&self) -> bool;
}

impl BrokenPipeError for anyhow::Error {
    fn is_broken_pipe(&self) -> bool {
        my_matches!(self.downcast_ref::<std::io::Error>(),
            Some(ioe) if ioe.kind() == std::io::ErrorKind::BrokenPipe)
    }
}

impl<T> BrokenPipeError for anyhow::Result<T> {
    fn is_broken_pipe(&self) -> bool {
        match self {
            Err(ref err) => err.is_broken_pipe(),
            _ => false,
        }
    }
}