Search code examples
rustreferencereference-typeowned-types

Storing references on structures and deserializing them


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.


Solution

  • 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.