use std::{
collections::BTreeMap,
path::{Path, PathBuf},
};
use serde::Deserialize;
use crate::{
config::{
emit::EmitConfig,
profile::{ProfileSettings, ResolvedProfile, resolve_profile},
},
error::{CliError, CliResult},
};
pub mod emit;
pub mod profile;
const CONFIG_FILE: &str = "Factorio.toml";
fn default_source() -> String {
"src".to_string()
}
fn default_output_dir() -> String {
"dist".to_string()
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct ModConfig {
pub title: Option<String>,
pub description: Option<String>,
pub factorio_version: Option<String>,
pub thumbnail: Option<String>,
}
impl Default for ModConfig {
fn default() -> Self {
Self {
title: None,
description: None,
factorio_version: Some("2.0".to_string()),
thumbnail: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Config {
#[serde(default = "default_source")]
pub source: String,
#[serde(default = "default_output_dir")]
pub output_dir: String,
#[serde(default)]
pub emit: EmitConfig,
#[serde(default)]
pub r#mod: ModConfig,
#[serde(default)]
pub profiles: BTreeMap<String, ProfileSettings>,
}
impl Config {
pub fn load(project_root: &Path) -> CliResult<Self> {
let config_path = project_root.join(CONFIG_FILE);
let contents =
std::fs::read_to_string(&config_path).map_err(|source| CliError::ReadFile {
path: config_path.clone(),
source,
})?;
toml::from_str(&contents).map_err(|source| CliError::ConfigParse {
path: config_path,
source,
})
}
pub fn config_path(project_root: &Path) -> PathBuf {
project_root.join(CONFIG_FILE)
}
#[must_use]
pub fn resolve_profile(&self, profile_name: &str) -> ResolvedProfile {
resolve_profile(&self.profiles, profile_name)
}
}