2017-09-15 50 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