nogo/error_handling/
mod.rs1pub mod validation;
5
6use std::io::{self, Write};
7use std::error::Error;
8use std::fmt;
9
10
11#[derive(Debug)]
13pub enum NogoErrorKind {
14 IncorrectNumberOfArgs,
15 IncorrectTypes,
16 InvalidBoardDimensions,
17 CantOpenFileForSaving,
18 CantOpenFileForReading,
19 ErrorReadingGameFile,
20 EOFWaitingForUserInput,
21 SystemIOError,
22 ParsingError,
23}
24
25#[derive(Debug)]
26pub struct NogoError<'a> {
27 kind: NogoErrorKind,
28 status: i32,
29 general: &'a str,
30 specific: &'a str,
31}
32
33impl<'a> fmt::Display for NogoError<'a> {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 write!(f, "{}", self.specific)
36 }
37}
38
39impl<'a> Error for NogoError<'a> {
40 fn description(&self) -> &str {
41 self.specific
42 }
43}
44
45impl<'a> NogoError<'a> {
46 pub fn new(kind: NogoErrorKind) -> Self {
47 let mut error = NogoError {
48 kind: kind,
49 status: 0,
50 general: "",
51 specific: "",
52 };
53
54 match error.kind {
55 NogoErrorKind::IncorrectNumberOfArgs => {
56 error.status = 1;
57 error.general = "Program started with incorrect number of arguments";
58 }
59
60 NogoErrorKind::IncorrectTypes => {
61 error.status = 2;
62 error.general = "Invalid type(s)";
63 }
64
65 NogoErrorKind::InvalidBoardDimensions => {
66 error.status = 3;
67 error.general = "Invalid board dimension(s)";
68 }
69
70 NogoErrorKind::CantOpenFileForReading => {
71 error.status = 4;
72 error.general = "Unable to open save file";
73 }
74
75 NogoErrorKind::ErrorReadingGameFile => {
76 error.status = 5;
77 error.general = "Incorrect save file contents";
78 }
79
80 NogoErrorKind::EOFWaitingForUserInput => {
81 error.status = 6;
82 error.general = "End of input from user";
83 }
84
85 NogoErrorKind::CantOpenFileForSaving => {
86 error.status = 7;
87 error.general = "Unable to open new save file";
88 }
89
90 NogoErrorKind::SystemIOError => {
91 error.status = 8;
92 error.general = "System IO error";
93 }
94
95 NogoErrorKind::ParsingError => {
96 error.status = 9;
97 error.general = "Error while parsing value";
98 }
99 }
100
101 error
102 }
103
104 pub fn kind(&self) -> &NogoErrorKind {
105 &self.kind
106 }
107
108 pub fn status(&self) -> i32 {
109 self.status
110 }
111
112 pub fn general(&self) -> &'a str {
113 &self.general
114 }
115
116 pub fn specific(&self) -> &'a str {
117 &self.specific
118 }
119
120 pub fn set_specific(&mut self, msg: &'a str) {
121 self.specific = msg;
122 }
123}
124
125impl<'a> ::std::convert::From<io::Error> for NogoError<'a> {
127 fn from(_: io::Error) -> Self {
128 NogoError::new(NogoErrorKind::SystemIOError)
129 }
130}
131
132impl<'a> ::std::convert::From<::std::num::ParseIntError> for NogoError<'a> {
134 fn from(_: ::std::num::ParseIntError) -> Self {
135 NogoError::new(NogoErrorKind::ParsingError)
136 }
137}
138
139
140pub type Result<'a, T> = ::std::result::Result<T, NogoError<'a>>;
142
143
144pub fn clean_exit() {
148 println!("\nThank you for playing nogo!\n");
149 ::std::process::exit(0);
150}
151
152pub fn exit_with_error(error: NogoError) {
154 writeln!(io::stderr(), "Error: {}", error.description()).unwrap();
155 ::std::process::exit(error.status());
156}
157
158
159pub fn construct_error(specific: &str, kind: NogoErrorKind) -> NogoError {
161 let mut err = NogoError::new(kind);
162 err.set_specific(specific);
163 err
164}