ed_journals/modules/logs/
log_dir.rs

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
use std::path::{Path, PathBuf};

use thiserror::Error;

use crate::modules::logs::{LogFile, LogFileError};

/// Provides an abstraction for all the log files in the journal directory.
#[derive(Debug)]
pub struct LogDir {
    dir_path: PathBuf,
}

#[derive(Debug, Error)]
pub enum LogDirError {
    #[error("Failed to represent OS string")]
    FailedToRepresentOsString,

    #[error(transparent)]
    JournalFileError(#[from] LogFileError),

    #[error(transparent)]
    IO(#[from] std::io::Error),
}

impl LogDir {
    pub fn new(dir_path: PathBuf) -> LogDir {
        LogDir { dir_path }
    }

    pub fn path(&self) -> &Path {
        self.dir_path.as_path()
    }

    /// Returns a list of journal log files found in the directory in any order.
    pub fn journal_logs(&self) -> Result<Vec<LogFile>, LogDirError> {
        self.dir_path
            .read_dir()?
            .filter_map(|entry| match entry {
                Ok(entry) => match LogFile::try_from(entry) {
                    Ok(journal_file) => Some(Ok(journal_file)),
                    Err(LogFileError::IncorrectFileName) => None,
                    Err(err) => Some(Err(err.into())),
                },
                Err(err) => Some(Err(err.into())),
            })
            .collect::<Result<Vec<LogFile>, LogDirError>>()
    }

    /// Returns a list of journal log files found in the directory, returning the oldest journal
    /// logs first.
    pub fn journal_logs_oldest_first(&self) -> Result<Vec<LogFile>, LogDirError> {
        let mut logs = self.journal_logs()?;
        logs.sort();

        Ok(logs)
    }

    /// Returns a list of journal log files found in the directory, returning the newest journal
    /// logs first.
    pub fn journal_logs_newest_first(&self) -> Result<Vec<LogFile>, LogDirError> {
        let mut logs = self.journal_logs()?;
        logs.sort();
        logs.reverse();

        Ok(logs)
    }
}

#[cfg(test)]
mod tests {
    use std::env::current_dir;

    use crate::logs::LogDir;

    #[test]
    fn journal_files_oldest_first_are_returned_in_the_correct_order() {
        let dir_path = current_dir().unwrap().join("test-files").join("journals");

        let journal_dir = LogDir::new(dir_path);

        let mut journal_files = journal_dir.journal_logs_oldest_first().unwrap().into_iter();

        let journal_1 = journal_files.next().unwrap();
        let journal_2 = journal_files.next().unwrap();

        let date_1 = journal_1.date_time();
        let date_2 = journal_2.date_time();

        assert!(date_2 > date_1);
    }

    #[test]
    fn journal_files_newest_first_are_returned_in_the_correct_order() {
        let dir_path = current_dir().unwrap().join("test-files").join("journals");

        let journal_dir = LogDir::new(dir_path);

        let mut journal_files = journal_dir.journal_logs_newest_first().unwrap().into_iter();

        let journal_1 = journal_files.next().unwrap();
        let journal_2 = journal_files.next().unwrap();

        let date_1 = journal_1.date_time();
        let date_2 = journal_2.date_time();

        assert!(date_2 < date_1);
    }
}