Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Configuration lib用于以符合人体工程学的方式进行配置处理_Configuration_Rust - Fatal编程技术网

Configuration lib用于以符合人体工程学的方式进行配置处理

Configuration lib用于以符合人体工程学的方式进行配置处理,configuration,rust,Configuration,Rust,我正在编写一个用于加载和处理应用程序配置的公共库, 使用 我试图让它尽可能符合人体工程学的用户,但似乎无法找出它 我的图书馆: impl RunEnv { fn to_string(&self) -> String { match self { RunEnv::Production => "prod".to_string(), RunEnv::Dev => "dev".to_string(),

我正在编写一个用于加载和处理应用程序配置的公共库,
使用

我试图让它尽可能符合人体工程学的用户,但似乎无法找出它

我的图书馆:

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)
    }
}
这是我的问题,我试图“隐藏”
.unwrap().try_into().unwrap()分开
因此,lib用户只需要定义他的
setting.rs
并运行
let conf:Settings=Settings::new()

如果我将
.try_into()
移动到一个trait中,那么我会遇到一个错误,我找不到解决方法:

   |         s.try_into()
   |           ^^^^^^^^ the trait `_IMPL_DESERIALIZE_FOR_Configuration::_serde::Deserialize<'_>` is not implemented for `config::config::Config`
| s.尝试()

|^^^^^^^^^^特性`“为配置实现反序列化::\u serde::反序列化为惯例,
新建
函数是构建实例的方法,必须是结构的固有方法, 直接在类型上可用的方法

在您的示例中,您试图将
new
定义为特征默认方法。 如果可能,签名应为:

pub trait LoadConfig {
  fn new() -> Self {

  }
}
这样的特质方法是不可能实现的,因为特质对
Self
具体类型一无所知

要遵循此约定,最好将
LoadConfig::new
trait方法重命名为其他方法:

pub trait LoadConfig {
  fn load() -> Result<Config, ConfigError>;
}

请注意,一个健壮的实现不应该
unwrap
,而应该更明确地管理配置错误

谢谢您的回答,您不是想为设置编写
impl LoadConfig
?如果可能的话,我会尽量保留trait中的所有逻辑和错误处理,因为配置加载在任何地方都是一样的,我讨厌在每个应用程序(impl部分)中都有相同的代码。不,你需要一个
新的
固有方法或一种构建应用程序结构的方法,而且不可能使用默认的trait方法。我已经更新了答案,希望能有所帮助。新impl中没有太多逻辑,它只是一个示例,config应该作为参数ecc传递。ecc。
pub trait LoadConfig {
  fn new() -> Self {

  }
}
pub trait LoadConfig {
  fn load() -> Result<Config, ConfigError>;
}
impl Settings {

    fn new() -> Settings {
        let config = Settings::load().unwrap(); // TBD: manage errors

        let port: u32 = config.get("port").unwrap_or("8080").parse().unwrap();

        Settings {
            server: Server {
                port: port,
                address: config.get("address").unwrap_or("localhost").to_owned()
            },
            run_mode: None
        }
    }
}