superstator
superstator

Reputation: 3208

"Not general enough" error deserializing YAML

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

Answers (2)

OliPro007
OliPro007

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

superstator
superstator

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

Related Questions