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

use chrono::prelude::*;

use crate::{
    errors::DiaryError,
    utils::file_system::{get_entry, get_entry_path},
};

pub struct ConfigBuilder {
    diary_path: PathBuf,
    prefix: String,
}

impl ConfigBuilder {
    fn new() -> Self {
        Self {
            diary_path: PathBuf::from(""),
            prefix: String::from("diary"),
        }
    }

    pub fn diary_path(mut self, diary_path: PathBuf) -> Self {
        self.diary_path = diary_path;
        self
    }
    pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
        self.prefix = prefix.into();
        self
    }

    pub fn build(self) -> Config {
        let Self { diary_path, prefix } = self;
        Config { diary_path, prefix }
    }
}

/// A representation of the cli-diary config file.
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
    diary_path: PathBuf,
    prefix: String,
}

impl Config {
    pub fn builder() -> ConfigBuilder {
        ConfigBuilder::new()
    }

    pub fn diary_path(&self) -> &PathBuf {
        &self.diary_path
    }

    pub fn prefix(&self) -> &String {
        &self.prefix
    }

    pub fn initialised(&self) -> Result<(), DiaryError> {
        if self.diary_path == PathBuf::from("") {
            Err(DiaryError::UnInitialised { source: None })
        } else {
            Ok(())
        }
    }
    pub fn get_entry_path(&self, date: &Date<Local>) -> PathBuf {
        get_entry_path(self.diary_path.to_path_buf(), date, &self.prefix)
    }

    pub fn get_entry_file(&self, date: &Date<Local>) -> io::Result<File> {
        get_entry(self.diary_path.to_path_buf(), date, &self.prefix)
    }
}

impl ::std::default::Default for Config {
    /// Creates a default Config, used when the user doesn't have a config initialised.
    fn default() -> Self {
        Self {
            diary_path: PathBuf::from(""),
            prefix: String::from("diary"),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    use super::Config;

    #[test]
    fn full_config_build() {
        let cfg = Config::builder()
            .diary_path(PathBuf::from("/home/"))
            .prefix("dy")
            .build();

        assert_eq!(cfg.prefix(), "dy");
        assert_eq!(cfg.diary_path(), &PathBuf::from("/home/"))
    }
}