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
//! System for logging time entries in a text-log-based format.
//!
//! The [`rtimelog`](../rtimelog/index.html) application applies these concepts as a command line
//! tool.
//!
//! This library supports the various concepts that go into making a timelog.
//! The core functionality is based around the concepts:
//!
//! - [`Day`](day::Day) - a container for events that we wish to track
//! - [`Entry`](entry::Entry) - a task to be accomplished as a continuous chunk of time
//! - [`Logfile`](logfile::Logfile) - list of all the that events started by the program
//! - [`Stack`](stack::Stack) - a stack of tasks that we may want to go back to
//!
//! Further support for working these events is supplied by:
//!
//! - [`Cli`](cli::Cli) - Handles the functionality provided by the command line tool
//! - [`Config`](config::Config) - Wrap the configuration information in an object
//! - [`Date`](date::Date) - A utility type that simplifies working with dates (including parsing,
//! etc.)
//! - [`DateRange`](date::DateRange) - A pair of [`Date`]s representing a half-open range of days.
//! - [`DateTime`](date::DateTime) - A utility type that simplifies working with date/times
//! (including parsing, etc.)
//! - [`Error`](error::Error) - an enumeration of the errors that can be encountered in processing
//! timelogs
//! - [`Result`] - Result specialized for [`Error`](error::Error)
//! - [`TaskEvent`](task::TaskEvent) - Type representing a single entry tracked by timelog.
//! - [`TaskLineIter`](task_line_iter::TaskLineIter) - an iterator for walking the entry lines in a
//! timelog file

#![warn(clippy::cast_lossless)]
#![warn(clippy::return_self_not_must_use)]
#![warn(clippy::uninlined_format_args)]
#![warn(clippy::unwrap_used)]

extern crate chrono;
extern crate clap;
extern crate configparser;
extern crate regex;
extern crate tilde_expand;
extern crate xml;

#[cfg(test)]
extern crate spectral;

#[cfg(test)]
extern crate tempfile;

pub(crate) mod archive;
pub mod chart;
pub mod cli;
pub mod config;
pub mod date;
pub mod day;
pub mod entry;
pub mod error;
pub mod file;
pub mod logfile;
pub(crate) mod macros;
pub mod stack;
pub mod task;
pub mod task_line_iter;

/// Command line parser and application driver
pub use cli::Cli;

/// Wrapper for configuration information
pub use config::Config;

/// Wrapper for Dates as used in the crate
pub use date::Date;

/// Wrapper for a range of Dates.
pub use date::DateRange;

/// Wrapper for Date/Times as used in the crate
pub use date::DateTime;

/// Represention of a day as a set of times, entries, and durations.
pub use day::Day;

/// Module representing an entry in the timelog
pub use entry::Entry;

/// An error that occurs in the working with timelogs
pub use error::Error;

/// Interface to the logfile for the timelog application.
pub use logfile::Logfile;

/// Interface to the stack file for the timelog application.
pub use stack::Stack;

/// Type representing a single task entry.
pub use task::TaskEvent;

/// Iterator for walking task lines
pub use task_line_iter::TaskLineIter;

/// Result type for timelog
pub type Result<T> = std::result::Result<T, Error>;

use std::fs;
use std::io::{BufRead, BufReader};
use std::result;

// Utility function for dealing with the mess around the BufReader
pub(crate) fn buf_reader(file: fs::File) -> impl Iterator<Item = String> {
    BufReader::new(file)
        .lines()
        .map_while(result::Result::ok)
        .filter(|ln| !Entry::is_comment_line(ln))
}