languages-rs 0.1.0

An internationalization library for your projects
Documentation
use std::{env, path::Path};

#[derive(Clone, Copy)]
pub enum Format {
    Json,
    Toml,
}

impl Format {
    /// Check if the format is JSON.
    pub fn is_json(&self) -> bool {
        matches!(self, &Format::Json)
    }

    /// Check if the format is TOML.
    pub fn is_toml(&self) -> bool {
        matches!(self, &Format::Toml)
    }

    /// Get file extension for the format (`.toml` or `.json`).
    ///
    /// # Example
    /// ```rust
    /// use languages_rs::Format;
    ///
    /// assert_eq!(Format::Json.get_file_extension(), ".json");
    /// assert_eq!(Format::Toml.get_file_extension(), ".toml");
    /// ```
    pub fn get_file_extension(&self) -> &str {
        match self {
            Self::Json => ".json",
            Self::Toml => ".toml",
        }
    }
}

#[derive(Clone)]
pub struct Config {
    directory: String,
    format: Format,
    languages: Vec<String>,
}

impl Config {
    /// Create a new configuration.
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::{Config, Format};
    ///
    /// let config: Config = match Config::new("languages", Format::Json, vec!["en"]) {
    ///     Ok(config) => config,
    ///     Err(e) => {
    ///         eprintln!("Error: {}", e);
    ///         return;
    ///     },
    /// };
    /// ```
    pub fn new(directory: &str, format: Format, languages: Vec<&str>) -> anyhow::Result<Self> {
        let path = Path::new(&env::current_dir()?).join(directory);
        if !path.exists() {
            return Err(anyhow::Error::msg(format!(
                "Cannot find `{}` directory.",
                path.display()
            )));
        } else if !path.is_dir() {
            return Err(anyhow::Error::msg(format!(
                "The path `{}` is not a directory.",
                path.display()
            )));
        }

        Ok(Self {
            directory: path.display().to_string(),
            format,
            languages: languages.iter().map(|e| String::from(*e)).collect(),
        })
    }

    /// Get the default configuration.
    ///
    /// # Default
    /// ```json
    /// {
    ///     "directory": "languages/",
    ///     "format": "JSON",
    ///     "languages": []
    /// ```
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::Config;
    ///
    /// let config: Config = match Config::default() {
    ///     Ok(config) => config,
    ///     Err(e) => {
    ///         eprintln!("Error: {}", e);
    ///         return;
    ///     },
    /// };
    /// ```
    pub fn default() -> anyhow::Result<Self> {
        let path = Path::new(&env::current_dir()?).join("languages");
        if !path.exists() {
            std::fs::create_dir(&path)?;
        } else if !path.is_dir() {
            return Err(anyhow::Error::msg(format!(
                "The path `{}` is not a directory.",
                path.display()
            )));
        }

        Ok(Self {
            directory: path.display().to_string(),
            format: Format::Json,
            languages: Vec::new(),
        })
    }

    /// Get the languages directory.
    ///
    /// # Example
    /// ```rust, ignore
    /// use std::{env, path};
    ///
    /// use languages_rs::Config;
    ///
    /// let config = Config::default().unwrap();
    /// assert_eq!(
    ///     config.get_directory(),
    ///     format!(
    ///         "{}{}languages",
    ///         env::current_dir().unwrap().display(),
    ///         path::MAIN_SEPARATOR,
    ///     ),
    /// );
    /// ```
    pub fn get_directory(&self) -> String {
        self.directory.clone()
    }

    /// Change the languages directory.
    ///
    /// # Example
    /// ```rust, ignore
    /// use std::env;
    ///
    /// use languages_rs::Config;
    ///
    /// let mut config = Config::default().unwrap();
    /// assert!(config.set_directory("languages").is_ok());
    /// ```
    pub fn set_directory(&mut self, new_directory: &str) -> anyhow::Result<()> {
        let path = Path::new(&env::current_dir()?).join(new_directory);
        if !path.exists() {
            return Err(anyhow::Error::msg(format!(
                "Cannot find `{}` directory.",
                path.display()
            )));
        } else if !path.is_dir() {
            return Err(anyhow::Error::msg(format!(
                "The path `{}` is not a directory.",
                path.display()
            )));
        }

        self.directory = path.display().to_string();
        Ok(())
    }

    /// Get the format files.
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::{Config, Format};
    ///
    /// let config = Config::default().unwrap();
    /// assert_eq!(config.get_format(), Format::Json);
    /// ```
    pub fn get_format(&self) -> Format {
        self.format
    }

    /// Change the format files.
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::{Config, Format};
    ///
    /// let mut config = Config::default().unwrap();
    /// assert!(config.get_format().is_json());
    ///
    /// config.change_format(Format::Toml);
    /// assert!(config.get_format().is_toml());
    /// ```
    pub fn change_format(&mut self, new_format: Format) {
        self.format = new_format;
    }

    /// Get the availables languages.
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::Config;
    ///
    /// let config = Config::default().unwrap();
    /// assert_eq!(config.get_languages(), Vec::<String>::new());
    /// ```
    pub fn get_languages(&self) -> Vec<String> {
        self.languages.clone()
    }

    /// Add a new language to the languages list if it does not exist.
    ///
    /// # Example
    /// ```rust, ignore
    /// use languages_rs::Config;
    ///
    /// let mut config = Config::default().unwrap();
    /// assert_eq!(config.get_languages(), Vec::<String>::new());
    /// assert!(config.add_language(String::from("en")).is_ok());
    /// assert_eq!(config.get_languages(), vec![String::from("en")]);
    /// ```
    pub fn add_language(&mut self, language: String) -> anyhow::Result<()> {
        if self.languages.contains(&language) {
            return Err(anyhow::Error::msg(format!(
                "The language `{}` already exists.",
                language
            )));
        }

        self.languages.push(language);
        Ok(())
    }
}