Reputation: 3208
I am new to Rust, so I'm sure I'm failing to grok something elementary here, but...
I have a yaml config file, which I want to deserialize to a simple struct. In an earlier version I was able to do this ok from a string literal, but now that I've refactored it to read from a file, I get an error implementation of '_::_serde::Deserialize' is not general enough
. My function looks like:
fn read_config(file: &str) -> Result<Config, &'static str> {
match std::fs::read_to_string(file) {
Ok(yaml) => match serde_yaml::from_str(&yaml) {
Ok(c) => c,
Err(_) => Err("Failed to parse yaml config."),
},
Err(_) => Err("Could not open supplied config file"),
}
}
read_to_string
returns a Result<String>
, but the signature for serde_yaml::from_str
wants a &str
, that is, a borrow. When I give it a borrow, as above, I get the "not general enough" error. When I google that error, I see a lot of discussion about how the deserializer can't use borrowed data; I have to own it first. Isn't that what the original String
is? If from_str
can't use a borrow, why does it take a &str
as an argument? What am I missing here?
Upvotes: 1
Views: 453
Reputation: 415
The problem is not the string parameter you pass.
According to the documentation, from_str
returns a Result<T>
. In this case, you'd need to call the function with the expected type for T
. Here, it would be serde_yaml::from_str::<Config>(&yaml)
.
You'd also need to fix your return statement for c
. It would be Ok(c)
, not only c
.
Upvotes: 1
Reputation: 3208
Sure enough, I was missing something fundamental. The problem had nothing to do with borrows or ownership. I missed wrapping the final result in Ok()
, which screwed up the type inference for my call to from_str
. Revised function:
fn read_config(file: &str) -> Result<Config, &'static str> {
match std::fs::read_to_string(file) {
Ok(yaml) => match serde_yaml::from_str(&yaml) {
Ok(c) => Ok(c),
Err(_) => Err("Failed to parse yaml config."),
},
Err(_) => Err("Could not open supplied config file"),
}
}
Upvotes: 0