sinan 0.1.0

A Boilerplate for Rapid Axum Web Service Deployment.
Documentation
use std::fs;
use std::ops::{Deref, DerefMut};

use config::{File, FileFormat, FileSourceString};
use serde_json::json;

use crate::contracts::Facade;
use crate::error::Error;
use crate::facades::{Container, Template};
use crate::foundation::BASE_PATH;

#[derive(Debug, Clone)]
pub struct Config(config::Config);

impl Deref for Config {
    type Target = config::Config;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for Config {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

fn file_source(mut template: Template) -> eyre::Result<Vec<File<FileSourceString, FileFormat>>> {
    let glob = glob::glob(
        BASE_PATH
            .join("config/*.yaml")
            .to_str()
            .ok_or_else(|| Error::Message("invalid path".to_string()))?,
    )
    .map_err(|err| Error::Message(err.to_string()))?;

    let mut source = vec![];

    for path in glob.filter_map(Result::ok) {
        let content = fs::read_to_string(path)?;

        let rendered = template.render(&content, &json!({}))?;

        source.push(config::File::from_str(&rendered, FileFormat::Yaml))
    }

    Ok(source)
}

impl Facade for Config {
    fn new(container: &Container) -> Self {
        let template = container.get::<Template>().cloned().unwrap();

        let config = config::Config::builder()
            .add_source(file_source(template).unwrap())
            .build()
            .expect("Configuration error");

        Self(config)
    }
}