Skip to content
Snippets Groups Projects
cli.rs 922 B
Newer Older
Eduardo Trujillo's avatar
Eduardo Trujillo committed
use std::path::PathBuf;

use clap::{Clap, IntoApp};
use serde::de::DeserializeOwned;
use thiserror::Error;

use crate::config;

#[derive(Error, Debug)]
pub enum CliError {
    #[error(transparent)]
    ArgParse(#[from] clap::Error),
    #[error(transparent)]
    Config(#[from] config::ConfigError),
}

pub trait AppOpts: Clap {
    fn try_init() -> Result<Self, CliError> {
        pretty_env_logger::init();

        Self::try_parse().map_err(CliError::ArgParse)
    }
}

pub trait ConfigurableAppOpts<C: DeserializeOwned>: AppOpts {
    fn try_init_with_config() -> Result<(Self, C), CliError> {
        let opts = Self::try_init()?;

        let app = <Self as IntoApp>::into_app();

        let conf = config::from_default_paths(app.get_name(), &opts.get_additional_config_paths())
            .map_err(CliError::Config)?;

        Ok((opts, conf))
    }

    fn get_additional_config_paths(&self) -> Vec<PathBuf>;
}