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
use serde_json::error::Error as SerdeError;
use serde_json::Value;
use std::error;
use std::fmt;
use std::io::Error as IoError;

#[derive(Debug)]
pub enum ClientError {
    /// A notification was not sent due to an internal error.
    NotifyFailed,
    /// A request failed due to an internal error.
    RequestFailed,

    /// A request or a notification could not be sent due to a
    /// serialization error.
    SerializeFailed(SerdeError),

    /// The server response is an error
    ErrorReturned(Value),

    /// We failed to spawn xi-core, e.g. because it's not installed, the binary is faulty, etc.
    CoreSpawnFailed(IoError),
}

impl fmt::Display for ClientError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            ClientError::NotifyFailed => write!(f, "Failed to send a notification"),
            ClientError::RequestFailed => {
                write!(f, "Failed to send a request, or receive its response")
            }
            ClientError::ErrorReturned(ref value) => {
                write!(f, "The core returned an error: {:?}", value)
            }
            ClientError::SerializeFailed(ref e) => {
                write!(f, "failed to serialize a message: {}", e)
            }
            ClientError::CoreSpawnFailed(ref s) => {
                write!(f, "Failed to spawn xi-core due to error: {}", s)
            }
        }
    }
}

impl error::Error for ClientError {
    fn description(&self) -> &str {
        match *self {
            ClientError::NotifyFailed => "Failed to send a notification",
            ClientError::RequestFailed => "Failed to send a request or receive its response",
            ClientError::ErrorReturned(_) => "The core answered with an error",
            ClientError::SerializeFailed(_) => "Failed to serialize message",
            ClientError::CoreSpawnFailed(_) => "Failed to spawn xi-core",
        }
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        match *self {
            ClientError::SerializeFailed(ref serde_error) => Some(serde_error),
            ClientError::CoreSpawnFailed(ref io_error) => Some(io_error),
            _ => None,
        }
    }
}

impl From<SerdeError> for ClientError {
    fn from(err: SerdeError) -> Self {
        ClientError::SerializeFailed(err)
    }
}

impl From<IoError> for ClientError {
    fn from(err: IoError) -> Self {
        ClientError::CoreSpawnFailed(err)
    }
}

#[derive(Debug)]
pub enum ServerError {
    UnknownMethod(String),
    DeserializeFailed(SerdeError),
    Other(String),
}

impl fmt::Display for ServerError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            ServerError::UnknownMethod(ref method) => write!(f, "Unkown method {}", method),
            ServerError::Other(ref s) => write!(f, "Unkown error: {}", s),
            ServerError::DeserializeFailed(ref e) => write!(
                f,
                "Failed to deserialize the parameters of a request or notification: {}",
                e
            ),
        }
    }
}

impl error::Error for ServerError {
    fn description(&self) -> &str {
        match *self {
            ServerError::UnknownMethod(_) => "Unkown method",
            ServerError::Other(_) => "Unknown error",
            ServerError::DeserializeFailed(_) => {
                "Failed to deserialize the parameters of a request or notification"
            }
        }
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        if let ServerError::DeserializeFailed(ref serde_error) = *self {
            Some(serde_error)
        } else {
            None
        }
    }
}

impl From<String> for ServerError {
    fn from(s: String) -> Self {
        ServerError::Other(s)
    }
}

impl<'a> From<&'a str> for ServerError {
    fn from(s: &'a str) -> Self {
        ServerError::Other(s.to_string())
    }
}

impl From<SerdeError> for ServerError {
    fn from(err: SerdeError) -> Self {
        ServerError::DeserializeFailed(err)
    }
}