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
use self::super::util::uppercase_first; use std::io::Write; /// Enum representing all possible ways the application can fail. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum Error { /// Failed to parse the specified file because of the specified errors. FileParsingFailed { /// The file that failed to parse. desc: &'static str, /// The parsing errors that occured. errors: Vec<String>, }, /// An I/O error occured. /// /// This includes higher-level I/O errors like FS ones. Io { /// The file that failed to parse. desc: &'static str, /// The failed operation. /// /// This should be lowercase and imperative ("create", "open"). op: &'static str, }, /// A UI error, like a failure to creat a Window. Ui { /// The UI operation's description. /// /// This should be imperative. desc: &'static str, /// The failed operation, as returned by the UI framework. error: String, }, } impl Error { /// Get the executable exit value from an `Error` instance. /// /// # Examples /// /// ``` /// # use std::iter::FromIterator; /// # use poke_a_mango::Error; /// let mut out = Vec::new(); /// Error::Io { /// desc: "leaderboard", /// op: "write", /// }.print_error(&mut out); /// assert_eq!(String::from_iter(out.iter().map(|&i| i as char)), /// "Writing leaderboard failed.\n".to_string()); /// ``` pub fn print_error<W: Write>(&self, err_out: &mut W) { match *self { Error::FileParsingFailed { desc, ref errors } => { writeln!(err_out, "Failed to parse {}{}", desc, if errors.is_empty() { '.' } else { ':' }).unwrap(); for err in errors { writeln!(err_out, " {}", err).unwrap() } } Error::Io { desc, op } => { // Strip the last 'e', if any, so we get correct inflection for continuous times let op = uppercase_first(if op.ends_with('e') { &op[..op.len() - 1] } else { op }); writeln!(err_out, "{}ing {} failed.", op, desc).unwrap() } Error::Ui { desc, ref error } => writeln!(err_out, "Failed to {}: {}.", desc, error).unwrap(), } } /// Get the executable exit value from an `Error` instance. /// /// # Examples /// /// ``` /// # use std::process::exit; /// # use poke_a_mango::Error; /// assert_eq!(Error::FileParsingFailed { /// desc: "", /// errors: vec![], /// }.exit_value(), 1); /// ``` pub fn exit_value(&self) -> i32 { match *self { Error::FileParsingFailed { .. } => 1, Error::Io { .. } => 2, Error::Ui { .. } => 3, } } }