Requires that `'de` must outlive `'static` issue

Ever since I am adding #[derive(Debug, serde::Serialize, serde::Deserialize)] to all of my structures I am getting this issue with this particular structure:

    #[derive(Debug, serde::Serialize, serde::Deserialize)]
    pub struct Fields
    {
        pub data            : String,
        pub mode            : Vec<radio_options::Fields>,
    }
226 |         pub mode            : Vec<radio_options::Fields>,
    |         ^^^ requires that `'de` must outlive `'static`

error: lifetime may not live long enough

Not too sure why this is happening or what does this mean?

And if you want to see what is inside radio_options::Fields structure here it is:

    #[derive(Debug, serde::Serialize, serde::Deserialize)]
    pub struct Fields
    {
        pub name            : &'static str,
        pub status          : bool,
    }

update:

In this other structure:

pub struct ObjectSettings
{
    object_type         : Vec<object_settings::radio_options::Fields>,
    position            : [object_settings::three_d_lables::Fields; 3],
    size                : [object_settings::three_d_lables::Fields; 3],
    rotation            : [object_settings::three_d_lables::Fields; 3],
    texture             : object_settings::texture::Fields,
    color               : [f32; 4],
}

If I commented out this line:

object_type : Vec<object_settings::radio_options::Fields>, then the error from the other structure pub mode : Vec<radio_options::Fields>, would go away.

Fields contains a &'static str, but your deserializer cannot provide one, since deserializers are not 'static. For example: you try to deserialize a String in json format into Fields.

fn from_json(s: &String) -> Fields {
    // ...
}

How do you construct an instance of Field? You can't get a &'static str from a short-lived &String or String. At best you can have a predefined pool of valid name and error when encountered something not in the pool, but in this case you should use enum (most of time).

Anyway, the short, easy solution would be change name: &'static str to name: String so Field can own the name data itself.

2 Likes

If I understand you correctly

#[derive(Debug, serde::Serialize, serde::Deserialize)]
    pub struct Fields
    {
        pub name            : &'static str,
        pub status          : bool,
    }

let field = Fields{name: "name", status: true}

If I put field into json field and wrote to a file, and I tried to put the name structure field from the file to the field variable then it wouldn't work as &String is outlived?

Yeah. That's the case. You have to leak the file content to prevent it being outlived, but under almost all circumstance it's a bad idea.

If you stilll want to use &str then you have to annotate lifetimes like

pub struct Field<'n> {
    pub name: &'n str,
    pub status: bool,
}

But lifetime annotations are quite infectious and somewhat annoying to write. (and it makes dynamically changing name hard). So unless you find allocation Strings a performance bottleneck, just use a regular String.

If you want to be able to serialize a borrowed string and deserialize an owned one, I believe you can use Cow<'static, str> without much extra hassle.

3 Likes

Thanks for both of your suggestions :slight_smile:

Come to think of it I don't even need to save pub name : &'static str, at all.

Is it possible to do something like this:


    pub struct Fields
    {
        pub name            : &'static str,

        #[derive(Debug, serde::Serialize, serde::Deserialize)]
        pub status          : bool,
    }

let field = Fields{name: "name", status: true}

What should it be set to when deserializing, then?

As it is static it gets initlaised in the code with predefined names. the names must remain static and should not change so it doesn't need to get saved.

pub struct Fields
    {
        pub name            : &'static str,

        #[derive(Debug, serde::Serialize, serde::Deserialize)]
        pub status          : bool,
    }

let field = Fields{name: "name", status: true}

Am I able to do this by any chance?

But it isn't. When you're deserializing Fields from something, you're creating new Fields, not initialized to anything other then the data you're deserializing it from.

1 Like

So the data name name has to be declared as Cow<'static, str>?

For example:

#[derive(Debug, serde::Serialize, serde::Deserialize)]
    pub struct Fields
    {
        pub name            : Cow<'static, str>
        pub status          : bool,
    }

let field = Fields{name: "name", status: true}

How come Cow<'static, str> would work but not with &'static str though?

I see what you mean now, thanks then

Cow<'static, str> is a type that can either be a borrowed &'static str or an owned String. So the deserializer will just always produce an owned String in the field. It can't do that for &'static str because that type can't hold an owned String

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.