Repository: TabbyML/tabby
File: crates/tabby-common/src/config.rs (Rust)

Code before:
use crate::{
    api::code::CodeSearchParams,
    path::repositories_dir,
    terminal::{HeaderFormat, InfoMessage},
};

#[derive(Serialize, Deserialize, Default, Debug, Clone)]
pub struct Config {
    #[serde(default)]
    pub repositories: Vec<RepositoryConfig>,

    #[serde(default)]
    pub server: ServerConfig,

    #[serde(default)]
    pub model: ModelConfigGroup,

    #[serde(default)]
    pub completion: CompletionConfig,

    #[serde(default)]
    pub answer: AnswerConfig,
}

impl Config {
    pub fn load() -> Result<Self> {
        let cfg_path = crate::path::config_file();
        if !cfg_path.as_path().exists() {
            debug!(
                "Config file {} not found, apply default configuration",
                cfg_path.display()
            );
            return Ok(Default::default());
        }
        let mut cfg: Self = serdeconv::from_toml_file(cfg_path.as_path())
            .context(format!("Config file '{}' is not valid", cfg_path.display()))?;

        if let Err(e) = cfg.validate_dirs() {
            cfg = Default::default();
            InfoMessage::new(
                "Parsing config failed",
                HeaderFormat::BoldRed,
                &[
                    &format!(
                        "Warning: Could not parse the Tabby configuration at {}",
                        crate::path::config_file().as_path().to_string_lossy()
                    ),
                    &format!("Reason: {e}"),
                    "Falling back to default config, please resolve the errors and restart Tabby",
                ],
            )

Review comment (suggestion):
```suggestion
    pub additional_languages: AdditionalLanguages,
```

Code after:
use crate::{
    api::code::CodeSearchParams,
    languages,
    path::repositories_dir,
    terminal::{HeaderFormat, InfoMessage},
};

#[derive(Serialize, Deserialize, Default, Debug, Clone)]
pub struct Config {
    #[serde(default)]
    pub repositories: Vec<RepositoryConfig>,

    #[serde(default)]
    pub server: ServerConfig,

    #[serde(default)]
    pub model: ModelConfigGroup,

    #[serde(default)]
    pub completion: CompletionConfig,

    #[serde(default)]
    pub answer: AnswerConfig,

    #[serde(default)]
    pub additional_languages: Vec<languages::Language>,
}

impl Config {
    pub fn load() -> Result<Self> {
        let cfg_path = crate::path::config_file();
        if !cfg_path.as_path().exists() {
            debug!(
                "Config file {} not found, apply default configuration",
                cfg_path.display()
            );
            return Ok(Default::default());
        }
        let mut cfg: Self = serdeconv::from_toml_file(cfg_path.as_path())
            .context(format!("Config file '{}' is not valid", cfg_path.display()))?;

        if let Err(e) = cfg.validate_dirs() {
            cfg = Default::default();
            InfoMessage::new(
                "Parsing config failed",
                HeaderFormat::BoldRed,
                &[
                    &format!(
                        "Warning: Could not parse the Tabby configuration at {}",
                        crate::path::config_file().as_path().to_string_lossy()
                    ),