use std::env; use std::path::PathBuf; pub struct Configuration { // Default Base Directories, default to XDG dirs but can be // configured by users. pub config_directory: PathBuf, pub data_directory: PathBuf, pub output_directory: PathBuf, pub max_posts: u8, // Derived directories: Config pub remote_config: PathBuf, // Derived directories: Data pub posts_directory: PathBuf, pub archive_directory: PathBuf, pub static_directory: PathBuf, pub templates_directory: PathBuf, // Derived directories: Output pub blog_output_directory: PathBuf, pub archive_output_directory: PathBuf, } impl Configuration { pub fn new() -> Self { let config_directory = Configuration::directory( "BLOG_CONFIG_DIRECTORY", "XDG_CONFIG_HOME", ".config", "blog", ); let data_directory = Configuration::directory( "BLOG_DATA_DIRECTORY", "XDG_DATA_HOME", ".local/share", "blog", ); let output_directory = Configuration::directory("BLOG_OUTPUT_DIRECTORY", "XDG_CACHE_HOME", ".cache", "blog"); let max_posts: u8 = env::var("BLOG_MAX_POSTS") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(3); let remote_config = config_directory.join("blogremote"); let posts_directory = data_directory.join("posts"); let archive_directory = data_directory.join("archive"); let static_directory = data_directory.join("static"); let templates_directory = data_directory.join("templates"); let blog_output_directory = output_directory.join("blog"); let archive_output_directory = output_directory.join("archive"); Configuration { config_directory, data_directory, output_directory, max_posts, remote_config, posts_directory, archive_directory, static_directory, templates_directory, blog_output_directory, archive_output_directory, } } fn directory( user_override: &str, default_value: &str, home_fallback: &str, path: &str, ) -> PathBuf { match env::var(user_override) { Ok(directory) => PathBuf::from(directory), Err(_) => match env::var(default_value) { Ok(directory) => PathBuf::from(directory), Err(_) => match env::var("HOME") { Ok(directory) => PathBuf::from(directory).join(home_fallback), Err(_) => panic!( "Could not find required directory, {} or {} should be set and readable.", user_override, default_value ), }, }, } .join(path) } }