config.rs 3.37 KB
use std::fs::File;
use std::io::Read;
use image::{ DynamicImage, io::Reader as ImageReader };
use once_cell::sync::Lazy;
use serde::Deserialize;
use anyhow::Result;
use crate::routes::image::Size as ImageSize;

#[derive(Debug, Deserialize)]
struct Database { url :Option<String> }

#[derive(Debug, Deserialize)]
struct Locations { data   :String
                 , images :String
                 , upload :String }

#[derive(Debug, Deserialize)]
struct Size { width :u32
            , height :u32 }

#[derive(Debug, Deserialize)]
struct Sizes { large :Size
             , medium :Size
             , small :Size
             , thumbnail :Size }

#[derive(Debug, Deserialize)]
struct Copyright { image_path :String
                 , steganography :String
                 , exiv :String }

#[derive(Debug, Deserialize)]
pub(crate) struct ConfigFile { namespace :String
                             , database  :Database
                             , locations :Locations
                             , sizes     :Sizes
                             , copyright :Copyright }

pub(crate) struct Config { config_file :ConfigFile
                         , copyright_image :DynamicImage }

pub(crate) static CONFIG :Lazy<Config> =
    Lazy::new(|| Config::load().unwrap());

impl Config {
    pub fn load() -> Result<Self> {
        let filename = std::env::var("CONFIG")?;

        let mut buffer = vec![];
        let mut file = File::open(filename)?;

        file.read_to_end(&mut buffer)?;
        let mut config_file :ConfigFile = toml::from_slice(&buffer)?;

        config_file.database.url = match config_file.database.url {
            Some(url) => Some(url),
            None => std::env::var("DATABASE_URL").ok()
        };

        let copyright_image = ImageReader::open(&config_file.copyright.image_path)?
                            . with_guessed_format()?
                            . decode()?;

        Ok(Self { config_file, copyright_image })
    }

    pub fn namespace(&self) -> &str {
        self.config_file.namespace.as_str()
    }

    pub fn upload_dir(&self) -> &str {
        self.config_file.locations.upload.as_str()
    }

    pub fn images_dir(&self) -> &str {
        self.config_file.locations.images.as_str()
    }

    pub fn width(&self, size :ImageSize) -> Option<u32> {
        match size {
            ImageSize::Original => None,
            ImageSize::Large => Some(self.config_file.sizes.large.width),
            ImageSize::Medium => Some(self.config_file.sizes.medium.width),
            ImageSize::Small => Some(self.config_file.sizes.small.width),
            ImageSize::Thumbnail => Some(self.config_file.sizes.thumbnail.width),
        }
    }

    pub fn height(&self, size :ImageSize) -> Option<u32> {
        match size {
            ImageSize::Original => None,
            ImageSize::Large => Some(self.config_file.sizes.large.height),
            ImageSize::Medium => Some(self.config_file.sizes.medium.height),
            ImageSize::Small => Some(self.config_file.sizes.small.height),
            ImageSize::Thumbnail => Some(self.config_file.sizes.thumbnail.height),
        }
    }

    pub fn copyright_image(&self) -> &DynamicImage {
        &self.copyright_image
    }

    pub fn copyright_steganography(&self) -> &str {
        self.config_file.copyright.steganography.as_str()
    }

    pub fn copyright_exiv(&self) -> &str {
        self.config_file.copyright.exiv.as_str()
    }
}