Я пишу общую библиотеку для загрузки и обработки конфигурации для моих приложений,
, используя config crate .
Я пытаюсь сделать ее эргономичной c как возможно для пользователя, но не может понять это.
мой lib.rs:
impl RunEnv {
fn to_string(&self) -> String {
match self {
RunEnv::Production => "prod".to_string(),
RunEnv::Dev => "dev".to_string(),
RunEnv::Staging => "stag".to_string(),
}
}
}
impl FromStr for RunEnv {
type Err = String;
fn from_str(s: &str) -> Result<RunEnv, String> {
match s {
"dev" => Ok(RunEnv::Dev),
"stag" => Ok(RunEnv::Staging),
"prod" => Ok(RunEnv::Production),
_ => Err(format!("Could not parse {:?}", s)),
}
}
}
#[derive(Debug, StructOpt)]
#[structopt(name = "CLI Options", about = "Common CLI options for running applications")]
pub struct Arguments {
/// Run in a specific environment mode: dev, stag, prod.
// short and long flags (-e, --env) will be deduced from the field's name
#[structopt(short, long, default_value = "dev")]
pub env: RunEnv,
}
pub trait LoadConfig {
fn new() -> Result<Config, ConfigError>{
const PACKAGE_NAME: &'static str = env!("CARGO_PKG_NAME");
let mut s = Config::new();
let args = Arguments::from_args();
let mut conf_path = String::new();
match args.env {
RunEnv::Production => {
conf_path = format!("/path/to/config/{}/config.toml", PACKAGE_NAME);
}
RunEnv::Staging => {
conf_path = format!("/path/to/config/{}/config.toml", PACKAGE_NAME);
}
RunEnv::Dev => {
conf_path = "tests/config.toml".to_string();
}
}
// Start off by merging in the "default" configuration file
s.merge(File::with_name(&conf_path))?;
// Add in the current environment
// Default to 'dev' env
s.set("run_mode", args.env.to_string())?;
Ok(s)
}
}
В моем приложении:
setting.rs
#[derive(Debug, Deserialize)]
pub struct Server {
port: u32,
address: String,
}
#[derive(Debug, Deserialize)]
pub struct Settings {
server: Server,
run_mode: Option<String>,
}
impl LoadConfig for Settings {}
main.rs
fn main() {
let conf: Settings = Settings::new().unwrap().try_into().unwrap();
println!("{:?}", conf);
И вот моя проблема, Я пытаюсь «спрятать» часть .unwrap().try_into().unwrap();
, чтобы пользователь lib нужно только определить его setting.rs
и запустить let conf: Settings = Settings::new()
Если я перемещу .try_into()
внутри черты, я получаю ошибку, я не могу найти способ go вокруг:
| s.try_into()
| ^^^^^^^^ the trait `_IMPL_DESERIALIZE_FOR_Configuration::_serde::Deserialize<'_>` is not implemented for `config::config::Config`
Я новичок в ржавчине и, возможно, скучаю по некоторым очевидным вещам