FromJson custom trait (serde_json) fails with lifetime issue

I have a custom trait with a default implementation from_json() that’s pretty simple. It’s meant to be an easy way add constructors from json using serde.

It works fine with hardcoded json as a &str, but when I switch to using String in order to pull the json from a file, I get a lifetime error (that I think I expected).

Here’s the most basic example

pub trait FromJson<T: Deserialize<'static>> {
    fn from_json(json: String) -> Result<T, Error> {
        // `from_str()` requires an &str, not String
        // This is the problem, it requires &json to be `static, but this isn't
        let value: T = serde_json::from_str(&json)?;

#[derive(Debug, Deserialize)]
struct Person {
    name: String,
    active: bool,

impl FromJson<Person> for Person {}

pub fn main() {
    // This is a String because it will be loaded from a file
    let json = String::from(r##"
        "name": "Michael",
        "active": true

    let person = Person::from_json(json);

    println!("{:?}", person);

So, the issue is that serde’s from_str method requires a &'static str, and any slice from (or reference to) a String is not going to be static.

So, what are my options? Is there a way to load the contents of a json file into a static lifetime (I don’t see how, that’s the entire point of static, right?)

Or, can I somehow convert a lifetime?

Thanks for the thoughts :smile:

Change FromJson<T: Deserialize<'static>> to FromJson<T: for<'a> Deserialize<'a>>. That is where the 'static bound is coming from. The new way says that any lifetime should work, not just 'static.

1 Like

Well, that’s just amazing. I initially used 'static at the compiler’s suggestion, but I’m learning not to take the compiler suggestions unless I actually understand them.


The compiler is usually good, it’s just that this is one of the edge cases that compiler doesn’t handle properly.

1 Like

You can use T: DeserializeOwned instead for a simpler bound.