tasker_cli/config/
mod.rs

1use camino::{Utf8Path, Utf8PathBuf};
2use lib_tasker::{error::TaskerFailure, io::get_project_directories};
3use serde::{Deserialize, Serialize};
4use std::io::Write;
5
6#[derive(Debug, Serialize, Deserialize)]
7pub struct Configuration {
8    pub name: String,
9    pub language: Language,
10    pub to_do_path: Utf8PathBuf,
11}
12
13#[derive(Debug, Default, Serialize, Deserialize)]
14pub enum Language {
15    #[default]
16    English,
17    Spanish,
18}
19
20impl Configuration {
21    /// Returns a new configuration struct.
22    ///
23    /// # Errors
24    ///
25    /// Returns an error if it fails to determine the default paths for application
26    /// data, if it fails to deserialize the configuration file or if it fails
27    /// to determine the existence of the configuration path.
28    pub fn new(to_do_path: &Utf8Path) -> Result<Self, TaskerFailure> {
29        let config_path = Self::get_default_path()?;
30
31        match config_path.try_exists() {
32            Ok(true) => {
33                Ok(toml::from_str(&std::fs::read_to_string(config_path)?)?)
34            }
35            Ok(false) => {
36                let config = Self {
37                    name: "John Doe".to_string(),
38                    language: Language::default(),
39                    to_do_path: to_do_path.to_owned(),
40                };
41
42                config.save_config()?;
43
44                Ok(config)
45            }
46            Err(err) => Err(TaskerFailure::ProjectDirectoryError(err)),
47        }
48    }
49
50    /// Deserializes a configuration struct from the given file path.
51    ///
52    /// # Errors
53    ///
54    /// Returns an error if the given file path doesn't exist, or if it fails to
55    /// determine its existence.
56    pub fn from_given_file(
57        file_path: &Utf8Path,
58    ) -> Result<Self, TaskerFailure> {
59        match file_path.try_exists() {
60            Ok(true) => {
61                Ok(toml::from_str(&std::fs::read_to_string(file_path)?)?)
62            }
63            Ok(false) => Err(TaskerFailure::ProjectDirectoryError(
64                std::io::Error::from(std::io::ErrorKind::NotFound),
65            )),
66            Err(err) => Err(TaskerFailure::ProjectDirectoryError(err)),
67        }
68    }
69
70    /// Returns the default configuration path.
71    ///
72    /// # Errors
73    ///
74    /// Returns an error if it failes to determine the default configuration path
75    /// for the application or if said path is invalid UTF-8.
76    pub fn get_default_path() -> Result<Utf8PathBuf, TaskerFailure> {
77        let dirs = get_project_directories()?;
78
79        let mut config_dir =
80            Utf8PathBuf::try_from(dirs.config_dir().to_path_buf())?;
81        config_dir.push("tasker-cli.toml");
82
83        Ok(config_dir)
84    }
85
86    fn save_config(&self) -> Result<(), TaskerFailure> {
87        let mut config_file = std::fs::File::create(Self::get_default_path()?)?;
88
89        config_file.write_all(toml::to_string_pretty(self)?.as_bytes())?;
90
91        Ok(())
92    }
93}