I want to load nonce
from a toml config file. nonce
is retrieved in pub fn get_nonce()
. I'd like to instantiate the result to salt
of lazy_static macro type HarshBuilder
.
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)
}
The compiler returns an error:
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>`
So get_nonce()
returns an enum result of Result<String, ConfigError>
. This does not appear to satisfy salt Option<Vec<u8>>
. The attempt you see above is to convert Result
enum to Vec<u8>
. However, this does not fix the error.
Here is the HarshBuilder
trait implementation for review:
/// 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
}
Trait bounds and lifetime elision is still a subject that I'm trying to wrap my head around. I can really use some guidance. Perhaps, this may be the reason as to why the answer is not completely obvious for me here.
Since your get_nonce
function returns a Result
, you need to handle the possible error. There are three ways you can fix your code here:
get_nonce
never returns an error, you can simply change it so that it returns nonce
directly instead of Ok(nonce)
. unwrap
on the result to access the Vec<u8>
that's inside (and crash if you later change get_nonce
to generate errors). unwrap
s and use try!
or the ?
operator to propagate errors and catch them properly at some top-level point). The Option<Vec<u8>>
is a red herring, the important thing is the prototype of salt()
, and as you can see in the definition of salt
:
pub fn salt<T: Into<Vec<u8>>>(mut self, salt: T)
it expects an argument that satisfies the trait Into<Vec<u8>>
. From the documentation you can see that there are these generic implementations of Into<T>
:
From<T>
for U
implies Into<U>
for T
Into
is reflexive, which means that Into<T>
for T
is implemented. So you may pass to salt
either:
Vec<u8>
. T
if there is such From<T>
is implemented for Vec<u8>
. Into<Vec<u8>>
directly. Now, you have a value of type Result<Vec<u8>, ConfigError>
, that satisfies none of the above. And that is what all those error messages are trying to tell you.
The easy solution is to change your function into:
pub fn get_nonce() -> Vec<u8> {
....
nonce
}
If you cannot change that return type you can use unwrap()
to get the real value from a Result()
(and crash on error):
.length(7)
.salt(get_nonce().unwrap())
.init()
If the get_nonce()
function can really fail, then you would have to manage the error properly, maybe making your MASK
value of type Result<Harsh, ConfigError>
?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.