Smart way to store content of a static file in a module?

Hi everyone,

my plan is to have a struct to store all the static text data my program has to deal with.
I thought, that it would be nice, having a feature like dynamically loading the data which is necessary.

So, I created a new module called "static.rs".

static.rs should look a little bit like this:

struct Data {
    file1: Option<&str>,
    file2: Option<&str>,
    [...]
}

impl Data {
    fn new() -> Data {
        file1: Option::None,
        file2: Option::None,
        [...]
    }
}

static mut data: Data = Data::new();

pub unsafe fn get_file1_content -> &str {
    if data.file1.is_empty() {
        data.file1 = read_file();
    }

    data.file1.unwrap()
}

fn read_file_content(filename: &str) -> &str {
    let mut file: File = File::open(filename)
        .expect("Failed reading file");
    let mut content: String = String::new();
    file.read_to_string(&mut content)
        .expect("Failed reading file");
    content
}
[...]

Here, I am facing a couple of problems simultaneously.

  1. Is there a better way than having an "unsafe" global mutable variable in static.rs?
    static mut DATA: Data = Data::new() is unsafe code. As long as I have limited knowledge about rust, I would love to minimize the amount of unsafe code, that I have to maintain.

  2. The compiler complains about static lifetimes for &str values. I would prefer using &str instead of String to load the file contents only once and therefore, it will never be modified in any way. So, why does the compiler not let me use &str and forces me to use static lifetimes?

  3. Last but not least, if I try to return the value in get_file1_content() as String, then it complains, that String does not implement the copy trait. How can I write the code in a way in which I would like to do it?

What would be the best approach for my questions?

Thanks for any helpful answer

I suggest using the lazy_static crate.

Also, you might like the fs::read_to_string helper, so you don't have to deal with File manually.

BTW, it rarely makes sense to store &str in structs. In this case if you actually tried, you'd have to do weird things like Box::leak. When a struct isn't a temporary view of other data (typically scoped to a single function), use owned types like String.