//! A set of error types for cassiopeia use std::fmt::{self, Display, Formatter}; use std::{error::Error, io}; /// User errors that can occur when using cassiopeia /// /// None of these errors are the fault of the program, but rather /// fault of the user for giving invalid commands. They must never /// make the program crash, but instead need to print human friendly /// error messages. #[derive(Debug)] pub enum UserError { /// Trying to start a session when one exists ActiveSessionExists, /// Trying to stop a session when none exists NoActiveSession, /// Trying to create a second invoice on the same day SameDayInvoice, /// No work was done since the last invoice NoWorkInvoice, } impl Display for UserError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "You're doing it wrong!") } } impl Error for UserError {} pub type UserResult = Result; /// Errors that occur when parsing a file /// /// These errors can pre-maturely terminate the run of the program, /// but must print a detailed error about what is wrong. Also, /// because they are technically a superset of /// [`UserError`](self::UserError), one of the variants is an embedded /// user error. #[derive(Debug)] pub enum ParseError { /// An embedded user error /// /// This error means that the structure of the parsed file is /// wrong, with an invalid sequence of events expressed User(UserError), /// The requested file did not exist NoSuchFile, /// The file could not be read BadPermissions, /// The file could not be written to FileNotWritable, /// Other file related errors FileUnknown(String), /// An invalid keyword was found BadKeyword { line: usize, tokn: String }, /// A bad timestamp was found BadTimestamp { line: usize, tokn: String }, /// A bad date was found BadDate { line: usize, tokn: String }, /// An unknown parse error occured Unknown, } impl Display for ParseError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "The parsed file was bad :(") } } impl Error for ParseError {} pub type ParseResult = Result; impl From for ParseError { fn from(user: UserError) -> Self { ParseError::User(user) } } impl From for ParseError { fn from(e: io::Error) -> Self { use io::ErrorKind::*; match e.kind() { NotFound => Self::NoSuchFile, PermissionDenied => Self::BadPermissions, _ => Self::FileUnknown(format!("{}", e)), } } }