mod env_string;
mod utils;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::{fmt, fs};
use std::fmt::Display;
use std::path::PathBuf;
use lazy_static::lazy_static;
use log::{error, info, warn};
use regex::Regex;
use toml;
use crate::traits::Flux;
#[derive(Serialize, Deserialize, Debug)]
pub struct Configs {
pub env: Option<Vec<EnvConfig>>,
pub configs: Vec<Config>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "lowercase")]
pub enum EnvConfig {
Variable {
name: String,
value: String,
},
File(String),
Group {
name: String,
env: Vec<EnvConfig>,
},
}
#[derive(Serialize, Deserialize)]
pub struct Config {
pub env: String,
pub fluxes: Vec<Box<dyn Flux>>,
pub keys: HashMap<String, EnvString>,
}
impl fmt::Debug for Config {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Config")
.field("env", &self.env)
.field("fluxes", &format!("[{} fluxes]", self.fluxes.len()))
.field("keys", &self.keys)
.finish()
}
}
impl Configs {
pub fn from_json(file_path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
let file_content = fs::read_to_string(file_path)?;
let config = serde_json::from_str(&file_content)?;
Ok(config)
}
pub fn from_yaml(file_path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
let file_content = fs::read_to_string(file_path)?;
let config = serde_yaml::from_str(&file_content)?;
Ok(config)
}
pub fn from_toml(file_path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
let file_content = fs::read_to_string(file_path)?;
let config = toml::from_str(&file_content)?;
Ok(config)
}
pub fn from_file(file_path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
info!("Loading configuration from file: {}", file_path.display());
let file_extension = file_path.extension()
.and_then(std::ffi::OsStr::to_str)
.map(|s| s.to_lowercase());
info!("File extension: {:?}", file_extension);
match file_extension.as_deref() {
Some("json") | Some("jsonc") => Self::from_json(file_path),
Some("yaml") | Some("yml") => Self::from_yaml(file_path),
Some("toml") => Self::from_toml(file_path),
_ => {
error!("Unsupported file format for file: {}", file_path.display());
Err("Unsupported file format".into())
}
}
}
}