In C++ I can write something like the below, where struct ReferenceData
serves as a "global" source of data. It defaults to whatever is given by get_default_map()
. But users have the option to override it, if they need to.
#include <iostream>
#include <unordered_map>
struct ReferenceData {
using map_t = std::unordered_map<std::string, std::string>;
static void set(const std::string& key, const std::string& data) {
ReferenceData::get_map()[key] = data;
}
static std::string get(const std::string& key) {
return ReferenceData::get_map().at(key);
}
static void reset(const std::string& key, const std::string& data) {
ReferenceData::get_map() = ReferenceData::get_default_map();
}
private:
static map_t& get_map() {
static map_t ref_data = ReferenceData::get_default_map();
return ref_data;
}
static map_t get_default_map() {
return {{"USD","NYC,UTC-5"}, {"GBP","LDN,UTC+0"}, {"JPY","TOK,UTC+9"}};
}
};
int main()
{
std::cout << "JPY = " << ReferenceData::get("JPY") << "\n"; // TOK,UTC+9
ReferenceData::set("JPY", "TYO,UTC+10");
std::cout << "JPY = " << ReferenceData::get("JPY") << "\n"; // TYO,UTC+10
return 0;
}
How does one implement this pattern in Rust? I have tried something like the below, but I am already failing at the get_map()
function implementation. Because
use std::collections::HashMap;
pub struct ReferenceData;
impl ReferenceData {
fn get_map() -> &'static HashMap<String, String> {
static ref_data: HashMap<String, String> = HashMap::new();
&ref_data
}
}
gives this compiler error:
error[E0015]: calls in statics are limited to constant functions,
tuple structs and tuple variants
--> src\ref_data.rs:7:51
|
7 | static cal_map: HashMap<String, String> = HashMap::new();
| ^^^^^^^^^^^^^^
Ideally, I don't want to use any external crates (like lazy_static). Unless it's the only way. Is it possible to replicate the same C++ pattern in Rust?