Storing references on structures and deserializing them

98 Views Asked by At

I am parsing a toml config file and retrieve it's content into some structs, using serde and toml.

So, a config structure could be defined like:

#[derive(Deserialize, Debug)]
pub struct Config<'a> {
    #[serde(borrow)]
    pub server: Inner<'a>
}

and another related:

#[derive(Deserialize, Debug)]
pub struct Inner<'a> {
    pub iprop1: &'a str,
    pub iprop2: &'a str,
}

This is the pub interface exposed for loading the config:

pub fn load() -> Config<'static> {

    let config_file: String = fs::read_to_string(CONFIG_FILE_IDENTIFIER)
        .expect("Error opening or reading the configuration file");

    toml::from_str(config_file.as_str())
        .expect("Error generating the configuration")
}

So, the issue it's clear. I can return data owned by the load() function.

I could change all the &str refereneces to String, because I am not able to fully comprehend how to properly play with references in Rust, but I would like to know, if there's another way to validate those references with lifetimes in Rust, so my structs can start to hold references instead owned values.

1

There are 1 best solutions below

4
cdhowie On BEST ANSWER

References refer to data owned elsewhere. For this to work, the data being referred to must live at least as long as the reference, otherwise you have a reference to data that no longer exists.

In your load() function, the return type declares that Config will borrow data that is 'static. This is a special lifetime that refers to data that is valid for the entire lifetime of the program.

However, toml::from_str() here borrows from config_file, which does not live for the entire lifetime of the program. It lives only until load() returns. You are attempting to return a reference to data owned by a function local, which is impossible, because the data will be destroyed before the returned reference can ever be used.

If there is nowhere else for config_file to live, the data should indeed be owned by the Config structure. The way you express that is by using String instead of &str within that structure.