Is there a clean way to have global mutable state in the Rust plugin?

The only way I found this is with an unsafe singleton function:

fn singleton() -> &'static mut HashSet<String> {
    static mut hash_map: *mut HashSet<String> = 0 as *mut HashSet<String>;

    let map: HashSet<String> = HashSet::new();
    unsafe {
        if hash_map == 0 as *mut HashSet<String> {
            hash_map = mem::transmute(Box::new(map));
        }
        &mut *hash_map
    }
}

Is there a better way? Perhaps we could do something in the function plugin_registrar?

In a global mutable state, I mean a mutable variable that can be used by several procedural macros and / or attributes.

Update:

I am writing a compiler plugin to provide a procedural macro sql!. I have an attribute #[sql_table]that will be used in structures so that I can get the name and columns of the SQL table.

I need a global mutable state to store the name and attribute fields structin an attribute so that the procedural macro can check if all identifiers exist.

+4
1

lazy_static! , . https://crates.io/crates/lazy_static/ - if hash_map == 0 as *mut HashSet<String>, , .

, , - , , Mutex.

:

#[macro_use] extern crate lazy_static;
use std::sync::Mutex;
use std::collections::HashSet;

lazy_static! {
    static ref THINGS: Mutex<HashSet<String>> = Mutex::new(HashSet::new());
}

fn usage() {
    // unwrap only fails if the lock is poisoned:
    // if another thread panicked while holding the lock.
    THINGS.lock().unwrap().insert("thing".to_owned())
}
+2

Source: https://habr.com/ru/post/1607199/


All Articles