Leon S.
Leon S.

Reputation: 3687

What is the Rust way to call a method requireing a string slice from a String

I'm a rust beginner (but experienced programmer), and I'm trying to create a simple utility function to read data from a json file and am clearly missing important rust-understanding to pull it off. I've looked around but I couldn't make it work from the other rust questions. I'm trying to do something like this:

pub fn read_data_from_json<'a, T: Deserialize<'a>, P: AsRef<Path>>(path: P) -> T {
    let result = std::fs::read_to_string(path).unwrap();
    return serde_json::from_str(&result).unwrap();
}

The problem is that I want to provide the serde_json::from_str() with the &str it requires, but get a String from reading the file. So the rust compiler says:

40 |     return serde_json::from_str(&result).unwrap();
   |            ---------------------^^^^^^^-
   |            |                    |
   |            |                    borrowed value does not live long enough

The cause is obviously that the result variable gets dropped before from_str() is done with the value, but I was unable to get 'just the slice' with the value. I've tried as_str(), &*, &'static str and several other options to try to make this work, but I'm clearly missing something, as it seems like a basic use-case. I must admit I'm still a bit fuzzy on 'lifetime' and the involved generics, so the problem might be there.

Upvotes: 1

Views: 387

Answers (1)

orlp
orlp

Reputation: 117846

I would suggest you to read Understanding deserializer lifetimes from the serde manual. There they suggest T: DeserializeOwned, explicitly mentioning your usecase:

Usually this is because the data that is being deserialized from is going to be thrown away before the function returns, so T must not be allowed to borrow from it.

So the solution is:

use serde::de::DeserializeOwned;

pub fn read_data_from_json<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> T {
    let result = std::fs::read_to_string(path).unwrap();
    return serde_json::from_str(&result).unwrap();
}

Upvotes: 4

Related Questions