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
147
148
149
150
151
152
153
154
155
use fann_sys::{fann_error, fann_get_errno, fann_get_errstr};
use fann_sys::fann_errno_enum::*;
use libc::c_int;
use self::FannErrorType::*;
use std::error::Error;
use std::fmt;
use std::ffi::CStr;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum FannErrorType {
CantOpenConfigR,
CantOpenConfigW,
WrongConfigVersion,
CantReadConfig,
CantReadNeuron,
CantReadConnections,
WrongNumConnections,
CantOpenTdW,
CantOpenTdR,
CantReadTd,
CantAllocateMem,
CantTrainActivation,
CantUseActivation,
TrainDataMismatch,
CantUseTrainAlg,
TrainDataSubset,
IndexOutOfBound,
ScaleNotPresent,
CantSaveFile,
ErrorCodeReturned,
}
impl fmt::Display for FannErrorType {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fmt::Display::fmt(match *self {
CantOpenConfigR => "Unable to open configuration file for reading",
CantOpenConfigW => "Unable to open configuration file for writing",
WrongConfigVersion => "Wrong version of configuration file",
CantReadConfig => "Error reading info from configuration file",
CantReadNeuron => "Error reading neuron info from configuration file",
CantReadConnections => "Error reading connections from configuration file",
WrongNumConnections => "Number of connections not equal to the number expected",
CantOpenTdW => "Unable to open train data file for writing",
CantOpenTdR => "Unable to open train data file for reading",
CantReadTd => "Error reading training data from file",
CantAllocateMem => "Unable to allocate memory",
CantTrainActivation => "Unable to train with the selected activation function",
CantUseActivation => "Unable to use the selected activation function",
TrainDataMismatch => "Irreconcilable differences between two Fann objects",
CantUseTrainAlg => "Unable to use the selected training algorithm",
TrainDataSubset => "Trying to take subset which is not within the training set",
IndexOutOfBound => "Index is out of bound",
ScaleNotPresent => "Scaling parameters not present",
CantSaveFile => "Failed saving file",
ErrorCodeReturned => "C function returned an error code but did not specify error",
}, f)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FannError {
pub error_type: FannErrorType,
pub error_str: String,
}
pub type FannResult<T> = Result<T, FannError>;
impl fmt::Display for FannError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
try!(self.error_type.fmt(f));
try!(": ".fmt(f));
self.error_str.fmt(f)
}
}
impl Error for FannError {
fn description(&self) -> &str {
&self.error_str[..]
}
}
impl FannError {
pub unsafe fn check_no_error(errdat: *mut fann_error) -> FannResult<()> {
if errdat.is_null() {
return Err(FannError {
error_type: FannErrorType::CantAllocateMem,
error_str: "Unable to create a new object".to_owned(),
});
}
let error_type = match fann_get_errno(errdat) {
FANN_E_NO_ERROR => return Ok(()),
FANN_E_CANT_OPEN_CONFIG_R => CantOpenConfigR,
FANN_E_CANT_OPEN_CONFIG_W => CantOpenConfigW,
FANN_E_WRONG_CONFIG_VERSION => WrongConfigVersion,
FANN_E_CANT_READ_CONFIG => CantReadConfig,
FANN_E_CANT_READ_NEURON => CantReadNeuron,
FANN_E_CANT_READ_CONNECTIONS => CantReadConnections,
FANN_E_WRONG_NUM_CONNECTIONS => WrongNumConnections,
FANN_E_CANT_OPEN_TD_W => CantOpenTdW,
FANN_E_CANT_OPEN_TD_R => CantOpenTdR,
FANN_E_CANT_READ_TD => CantReadTd,
FANN_E_CANT_ALLOCATE_MEM => CantAllocateMem,
FANN_E_CANT_TRAIN_ACTIVATION => CantTrainActivation,
FANN_E_CANT_USE_ACTIVATION => CantUseActivation,
FANN_E_TRAIN_DATA_MISMATCH => TrainDataMismatch,
FANN_E_CANT_USE_TRAIN_ALG => CantUseTrainAlg,
FANN_E_TRAIN_DATA_SUBSET => TrainDataSubset,
FANN_E_INDEX_OUT_OF_BOUND => IndexOutOfBound,
FANN_E_SCALE_NOT_PRESENT => ScaleNotPresent,
};
let errstr_bytes = CStr::from_ptr(fann_get_errstr(errdat)).to_bytes().to_vec();
let error_str_opt = String::from_utf8(errstr_bytes);
Err(FannError {
error_type: error_type,
error_str: error_str_opt.unwrap_or("Invalid UTF-8 in error string".to_owned()),
})
}
pub unsafe fn check_zero(result: c_int,
errdat: *mut fann_error,
error_str: &str) -> FannResult<()> {
try!(FannError::check_no_error(errdat));
match result {
0 => Ok(()),
_ => Err(FannError {
error_type: FannErrorType::ErrorCodeReturned,
error_str: error_str.to_owned(),
}),
}
}
}