2017-09-15 47 views
0

我想从toml配置文件加载nonce。在pub fn get_nonce()中检索到nonce。我想将lazy_static宏类型HarshBuilder的结果实例化为salt特性绑定T:从<结果<T, Error>>不满意

use config::{Config, File, FileFormat, ConfigError}; 
use harsh::{Harsh, HarshBuilder}; 
use settings::Server; 

const CFG_DEFAULT: &'static str = "conf/default"; 

lazy_static! { 
    static ref MASK: Harsh = HarshBuilder::new() 
     .length(7) 
     .salt(get_nonce()) 
     .init() 
     .expect("invalid harsh build"); 
} 

fn conf_file() -> Config { 
    let mut cfg = Config::default(); 
    cfg.merge(File::from_str(CFG_DEFAULT, FileFormat::Toml)) 
     .unwrap(); 

    cfg 
} 

pub fn get_nonce() -> Result<Vec<u8>, ConfigError> { 
    let conf = conf_file(); 
    let search: Server = conf.get("server").unwrap(); 
    let nonce: Vec<u8> = search.nonce.into_bytes(); 

    Ok(nonce) 
} 

编译器返回一个错误:

error[E0277]: the trait bound `std::vec::Vec<u8>: std::convert::From<std::result::Result<std::vec::Vec<u8>, config::ConfigError>>` is not satisfied 
--> lib.rs:40:14 
| 
40 |  .salt(get_nonce()) 
|   ^^^^ the trait 
| 
`std::convert::From<std::result::Result<std::vec::Vec<u8>, config::ConfigError>>` is not implemented for `std::vec::Vec<u8>` 

| 
= help: the following implementations were found: 
     <std::vec::Vec<u8> as std::convert::From<std::ffi::CString>> 
     <std::vec::Vec<u8> as std::convert::From<std::string::String>> 
     <std::vec::Vec<T> as std::convert::From<&'a mut [T]>> 
     <std::vec::Vec<T> as std::convert::From<std::borrow::Cow<'a, [T]>>> 
     and 5 others 
= note: required because of the requirements on the impl of `std::convert::Into<std::vec::Vec<u8>>` for `std::result::Result<std::vec::Vec<u8>, config::ConfigError>` 

所以get_nonce()返回Result<String, ConfigError>枚举结果。这似乎不符合salt Option<Vec<u8>>。您上面看到的尝试是将Result枚举转换为Vec<u8>。但是,这并不能解决这个错误。

这里是审查HarshBuilder特征实现:

/// Note that this factory will be consumed upon initialization. 
#[derive(Debug, Default)] 
pub struct HarshBuilder { 
    salt: Option<Vec<u8>>, 
    // ...ommitted for brevity 
} 

impl HarshBuilder { 
/// Creates a new `HarshBuilder` instance. 
pub fn new() -> HarshBuilder { 
    HarshBuilder { 
     salt: None, 
     // ...ommited for brevity 
    } 
} 

/// Note that this salt will be converted into a `[u8]` before use, meaning 
/// that multi-byte utf8 character values should be avoided. 
pub fn salt<T: Into<Vec<u8>>>(mut self, salt: T) -> HarshBuilder { 
    self.salt = Some(salt.into()); 
    self 
} 

特质界限,终身省音仍然是我试图绕到我的头一个问题。我真的可以使用一些指导。也许,这可能是为什么答案在我这里不是完全明显的原因。

回答

2

Option<Vec<u8>>是一个红色的鲱鱼,最重要的事情是salt()的原型,你可以在salt定义见:

pub fn salt<T: Into<Vec<u8>>>(mut self, salt: T) 

,预计满足特质Into<Vec<u8>>参数。从documentation你可以看到,也有Into<T>这些通用的实现:为T

  • Into

    • From<T>U意味着Into<U>是自反,这意味着Into<T>T实现。

    所以,你可以传递给salt之一:

    • Vec<u8>类型的值。
    • T如果有这样的值From<T>实施Vec<u8>
    • 直接执行Into<Vec<u8>>的值。

    现在,您有一个类型为Result<Vec<u8>, ConfigError>的值,它不符合上述任何一项。这就是所有这些错误信息试图告诉你的。

    最简单的解决办法是改变你的函数为:

    pub fn get_nonce() -> Vec<u8> { 
        .... 
        nonce 
    } 
    

    如果你不能改变(在错误和崩溃),您可以使用unwrap()获得从Result()实际值返回类型:

    .length(7) 
        .salt(get_nonce().unwrap()) 
        .init() 
    

    如果get_nonce()功能可以真的失败,那么你将不得不妥善管理错误,可能使MASK类型的值Result<Harsh, ConfigError>

  • +0

    感谢您深入解释这一点。 – Alex

    2

    由于您的get_nonce函数返回Result,您需要处理可能的错误。有三种方法,你可以在这里解决您的代码:

    • 鉴于get_nonce永远不会返回一个错误,你可以简单地改变它,这样它会返回nonce,而不是直接Ok(nonce)
    • 或者您可以致电unwrap查看结果以访问里面的Vec<u8>(如果您以后更改get_nonce以生成错误,则会崩溃)。
    • 或者你可以添加适当的错误处理(摆脱unwrap s和使用try!?运算符来传播错误并在某些顶级点正确捕获它们)。
    +0

    感谢您的意见。 – Alex