rtimelog 1.1.1

System for tracking time in a text-log-based format.
Documentation
//! An error that occurs in working with timelogs
use thiserror;

use crate::date;

/// Errors encountered accessing files and directories.
#[derive(Eq, thiserror::Error, Debug, PartialEq)]
pub enum PathError {
    /// Error accessing a file when reading. File is first string, error message is second.
    #[error("Error accessing file '{0}': {1}")]
    FileAccess(String, String),

    /// Error writing to a file. File is first string, error message is second.
    #[error("Error writing to file '{0}': {1}")]
    FileWrite(String, String),

    /// Required filename not supplied.
    #[error("Required filename not supplied")]
    FilenameMissing,

    /// Attempt to access a file in directory that is not available. Directory is first string,
    /// error message is second.
    #[error("Missing directory '{0}': {1}")]
    InvalidPath(String, String),

    /// Invalid path for the logfiles.
    #[error("Logfiles path contains invalid characters")]
    InvalidTimelogPath,

    /// Invalid path for the stack file.
    #[error("Stack file path contains invalid characters")]
    InvalidStackPath,

    /// Invalid path for the logfiles.
    #[error("Config path contains invalid characters")]
    InvalidConfigPath,

    /// The filename references an existing file.
    #[error("Cannot overwrite, '{0}' already exists")]
    AlreadyExists(String),

    /// The filename references an existing file. File is first string, error message is second.
    #[error("Cannot rename '{0}': {1}")]
    RenameFailure(String, String),

    /// Cannot create path. Path is first string, error message is second.
    #[error("Cannot create path '{0}': {1}")]
    CantCreatePath(String, String),

    /// Cannot read timelog
    #[error("Cannot read timelog")]
    CantReadTimelog,

    /// Cannot write to report file
    #[error("Cannot write report file")]
    CantWriteReport
}

/// Enumeration of errors that can happen processing timelogs
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
pub enum Error {
    /// Not a validly formatted entry line.
    #[error(transparent)]
    InvalidEntryLine {
        #[from]
        source: crate::entry::EntryError
    },

    /// Entry line is missing the required stamp.
    #[error("Missing required stamp.")]
    MissingDate,

    /// Invalid starting date in a date pair.
    #[error("Invalid starting date.")]
    StartDateFormat,

    /// Invalid ending date in a date pair.
    #[error("Invalid ending date.")]
    EndDateFormat,

    /// Unable to pop stack item.
    #[error("Unable to pop stack item")]
    StackPop,

    /// Invalid drop argument
    #[error("Invalid drop argument '{0}'")]
    InvalidDrop(String),

    /// Invalid drop argument
    #[error("Invalid pos integer argument '{0}'")]
    InvalidInt(String),

    /// Project descriptors invalid
    #[error("Bad project filters")]
    BadProjectFilter,

    /// Not a valid timelog command
    #[error("'{0}' is not a valid command")]
    InvalidCommand(String),

    /// Deprecated command
    #[error("Deprecated! Use '{0}' instead.")]
    DeprecatedCommand(&'static str),

    /// Failed to execute editor on logfile. File is first string, error message is second.
    #[error("Editor '{0}' failed to execute: {1}")]
    EditorFailed(String, String),

    /// Unexpected argument
    #[error("Argument '{0}' is unexpected")]
    UnexpectedArgument(String),

    /// Invalid argument for 'was'
    #[error("Argument '{0}' should have been a time")]
    InvalidWasArgument(String),

    /// Tried to change stop entry
    #[error("Cannot edit stop entry")]
    InvalidStopEdit,

    /// Tried to change ignore entry
    #[error("Cannot edit ignore entry")]
    InvalidIgnoreEdit,

    /// Errors in path/file handling
    #[error(transparent)]
    DateError {
        #[from]
        source: date::DateError
    },

    /// Errors in path/file handling
    #[error(transparent)]
    PathError {
        #[from]
        source: PathError
    }
}

impl From<xml::writer::Error> for Error {
    /// Conversion from an [`xml::writer::Error`] to a timelog [`enum@Error`].
    fn from(_e: xml::writer::Error) -> Error { PathError::CantWriteReport.into() }
}