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
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Standard error type for ocl futures.
//!

use std;
// use futures::Canceled as FuturesCanceled;
use futures::sync::oneshot::Canceled as OneshotCanceled;
use futures::sync::mpsc::SendError;
use core::error::Error as OclError;

pub type Result<T> = std::result::Result<T, self::Error>;

/// An enum containing either a `String` or one of several other error types.
///
/// Implements the usual error traits.
pub enum Error {
    Ocl(OclError),
    MpscSendError(String),
    OneshotCanceled(OneshotCanceled),
    // FuturesCanceled(FuturesCanceled),
    Other(Box<std::error::Error>),
}

impl self::Error {
    /// Returns a new `Error::String` with the given description.
    pub fn string<S: Into<String>>(desc: S) -> self::Error {
        self::Error::Ocl(OclError::String(desc.into()))
    }

    /// If this is a `String` variant, concatenate `txt` to the front of the
    /// contained string. Otherwise, do nothing at all.
    pub fn prepend<'s, S: AsRef<&'s str>>(&'s mut self, txt: S) {
        if let &mut Error::Ocl(OclError::String(ref mut string)) = self {
            string.reserve_exact(txt.as_ref().len());
            let old_string_copy = string.clone();
            string.clear();
            string.push_str(txt.as_ref());
            string.push_str(&old_string_copy);
        }
    }
}

impl std::error::Error for self::Error {
    fn description(&self) -> &str {
        match *self {
            Error::Ocl(ref err) => err.description(),
            Error::MpscSendError(ref err) => err,
            Error::OneshotCanceled(ref err) => err.description(),
            // Error::FuturesCanceled(ref err) => err.description(),
            Error::Other(ref err) => err.description(),
        }
    }
}

impl From<OclError> for self::Error {
    fn from(err: OclError) -> self::Error {
        Error::Ocl(err)
    }
}

impl From<self::Error> for OclError {
    fn from(err: self::Error) -> OclError {
        match err {
            Error::Ocl(err) => err,
            _ => format!("{}", err).into(),
        }
    }
}

impl<T> From<SendError<T>> for self::Error {
    fn from(err: SendError<T>) -> self::Error {
        let debug = format!("{:?}", err);
        let display = format!("{}", err);
        Error::MpscSendError(format!("{}: '{}'", debug, display))
    }
}

// impl From<FuturesCanceled> for self::Error {
//     fn from(err: FuturesCanceled) -> self::Error {
//         Error::FuturesCanceled(err)
//     }
// }

impl From<OneshotCanceled> for self::Error {
    fn from(err: OneshotCanceled) -> self::Error {
        Error::OneshotCanceled(err)
    }
}

impl From<Box<std::error::Error>> for self::Error {
    fn from(err: Box<std::error::Error>) -> self::Error {
        self::Error::Other(err)
    }
}

impl From<()> for self::Error {
    fn from(_: ()) -> self::Error {
        self::Error::Ocl(OclError::Void)
    }
}

impl From<String> for self::Error {
    fn from(desc: String) -> self::Error {
        self::Error::string(desc)
    }
}

impl<'a> From<&'a str> for self::Error {
    fn from(desc: &'a str) -> self::Error {
        self::Error::string(String::from(desc))
    }
}

impl From<std::ffi::NulError> for self::Error {
    fn from(err: std::ffi::NulError) -> self::Error {
        self::Error::Ocl(OclError::Nul(err))
    }
}

impl From<std::io::Error> for self::Error {
    fn from(err: std::io::Error) -> self::Error {
        self::Error::Ocl(OclError::Io(err))
    }
}

impl From<self::Error> for String {
    fn from(err: self::Error) -> String {
        err.to_string()
    }
}

impl std::fmt::Display for self::Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        f.write_str(self.description())
    }
}

impl std::fmt::Debug for self::Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        f.write_str(self.description())
    }
}

unsafe impl std::marker::Send for self::Error {}
unsafe impl std::marker::Sync for self::Error {}