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
//! Error handling for the learning module.

use std::boxed::Box;
use std::convert::Into;
use std::error;
use std::fmt;
use std::marker::{Send, Sync};

use rulinalg;

/// An error related to the learning module.
#[derive(Debug)]
pub struct Error {
    kind: ErrorKind,
    error: Box<dyn error::Error + Send + Sync>,
}

/// Types of errors produced in the learning module.
///
/// List intended to grow and so you should
/// be wary of matching against explicitly.
#[derive(Debug)]
pub enum ErrorKind {
    /// The parameters used to define the model are not valid.
    InvalidParameters,
    /// The input data to the model is not valid.
    InvalidData,
    /// The action could not be carried out as the model was in an invalid state.
    InvalidState,
    /// The model has not been trained
    UntrainedModel,
    /// Linear algebra related error
    LinearAlgebra
}

impl Error {
    /// Construct a new `Error` of a particular `ErrorKind`.
    pub fn new<E>(kind: ErrorKind, error: E) -> Error
        where E: Into<Box<dyn error::Error + Send + Sync>>
    {
        Error {
            kind: kind,
            error: error.into(),
        }
    }

    /// Returns a new error for an untrained model
    ///
    /// This function is unstable and may be removed with changes to the API.
    pub fn new_untrained() -> Error {
        Error::new(ErrorKind::UntrainedModel, "The model has not been trained.")
    }

    /// Get the kind of this `Error`.
    pub fn kind(&self) -> &ErrorKind {
        &self.kind
    }
}

impl From<rulinalg::error::Error> for Error {
    fn from(e: rulinalg::error::Error) -> Error {
        Error::new(ErrorKind::LinearAlgebra, <rulinalg::error::Error as error::Error>::description(&e))
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        self.error.description()
    }
}

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