languages_rs/
config.rs

1use std::{env, path::Path};
2
3#[derive(Clone)]
4pub struct Config {
5    directory: String,
6    languages: Vec<String>,
7}
8
9impl Config {
10    /// Create a new configuration.
11    ///
12    /// # Example
13    /// ```rust, ignore
14    /// use languages_rs::Config;
15    ///
16    /// let config: Config = match Config::new("languages", vec!["en"]) {
17    ///     Ok(config) => config,
18    ///     Err(e) => {
19    ///         eprintln!("Error: {}", e);
20    ///         return;
21    ///     },
22    /// };
23    /// ```
24    pub fn new(directory: &str, languages: Vec<&str>) -> anyhow::Result<Self> {
25        let path = Path::new(&env::current_dir()?).join(directory);
26        if !path.exists() {
27            return Err(anyhow::Error::msg(format!(
28                "Cannot find `{}` directory.",
29                path.display()
30            )));
31        } else if !path.is_dir() {
32            return Err(anyhow::Error::msg(format!(
33                "The path `{}` is not a directory.",
34                path.display()
35            )));
36        }
37
38        Ok(Self {
39            directory: path.display().to_string(),
40            languages: languages.iter().map(|e| String::from(*e)).collect(),
41        })
42    }
43
44    /// Get the default configuration.
45    ///
46    /// # Default
47    /// ```json
48    /// {
49    ///     "directory": "languages/",
50    ///     "languages": []
51    /// ```
52    ///
53    /// # Example
54    /// ```rust, ignore
55    /// use languages_rs::Config;
56    ///
57    /// let config: Config = match Config::default() {
58    ///     Ok(config) => config,
59    ///     Err(e) => {
60    ///         eprintln!("Error: {}", e);
61    ///         return;
62    ///     },
63    /// };
64    /// ```
65    pub fn default() -> anyhow::Result<Self> {
66        let path = Path::new(&env::current_dir()?).join("languages");
67        if !path.exists() {
68            std::fs::create_dir(&path)?;
69        } else if !path.is_dir() {
70            return Err(anyhow::Error::msg(format!(
71                "The path `{}` is not a directory.",
72                path.display()
73            )));
74        }
75
76        Ok(Self {
77            directory: path.display().to_string(),
78            languages: Vec::new(),
79        })
80    }
81
82    /// Get the languages directory.
83    ///
84    /// # Example
85    /// ```rust, ignore
86    /// use std::{env, path};
87    ///
88    /// use languages_rs::Config;
89    ///
90    /// let config = Config::default().unwrap();
91    /// assert_eq!(
92    ///     config.get_directory(),
93    ///     format!(
94    ///         "{}{}languages",
95    ///         env::current_dir().unwrap().display(),
96    ///         path::MAIN_SEPARATOR,
97    ///     ),
98    /// );
99    /// ```
100    pub fn get_directory(&self) -> String {
101        self.directory.clone()
102    }
103
104    /// Change the languages directory.
105    ///
106    /// # Example
107    /// ```rust, ignore
108    /// use std::env;
109    ///
110    /// use languages_rs::Config;
111    ///
112    /// let mut config = Config::default().unwrap();
113    /// assert!(config.set_directory("languages").is_ok());
114    /// ```
115    pub fn set_directory(&mut self, new_directory: &str) -> anyhow::Result<()> {
116        let path = Path::new(&env::current_dir()?).join(new_directory);
117        if !path.exists() {
118            return Err(anyhow::Error::msg(format!(
119                "Cannot find `{}` directory.",
120                path.display()
121            )));
122        } else if !path.is_dir() {
123            return Err(anyhow::Error::msg(format!(
124                "The path `{}` is not a directory.",
125                path.display()
126            )));
127        }
128
129        self.directory = path.display().to_string();
130        Ok(())
131    }
132
133    /// Get the availables languages.
134    ///
135    /// # Example
136    /// ```rust, ignore
137    /// use languages_rs::Config;
138    ///
139    /// let config = Config::default().unwrap();
140    /// assert_eq!(config.get_languages(), Vec::<String>::new());
141    /// ```
142    pub fn get_languages(&self) -> Vec<String> {
143        self.languages.clone()
144    }
145
146    /// Add a new language to the languages list if it does not exist.
147    ///
148    /// # Example
149    /// ```rust, ignore
150    /// use languages_rs::Config;
151    ///
152    /// let mut config = Config::default().unwrap();
153    /// assert_eq!(config.get_languages(), Vec::<String>::new());
154    /// assert!(config.add_language(String::from("en")).is_ok());
155    /// assert_eq!(config.get_languages(), vec![String::from("en")]);
156    /// ```
157    pub fn add_language(&mut self, language: String) -> anyhow::Result<()> {
158        if self.languages.contains(&language) {
159            return Err(anyhow::Error::msg(format!(
160                "The language `{}` already exists.",
161                language
162            )));
163        }
164
165        self.languages.push(language);
166        Ok(())
167    }
168}