Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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>;
}