init_guard/lib.rs
1//! # INIT GUARD
2//!
3//! The Init_Guard Crate provides a Synchronization Primitive, that can be used to guard against double initialization.
4//!
5//! For this, the init_guard macro is exported.
6//! The init_guard macro creates a new module that contains everything needed for the init_guard.
7//!
8//! The Module contains two public Methods, init() and has_init().
9//!
10//! ## has_init()
11//!
12//! The has_init function has the following definition:
13//!
14//! ```
15//! fn has_init() -> bool
16//! ```
17//!
18//! The has_init function returns true, if the init_guard was already initialized.
19//!
20//! ## init()
21//!
22//! The init function has the following definition:
23//!
24//! ```
25//! fn init() -> Result<(),()>
26//! ```
27//!
28//! The init function returns Ok, if the init_guard was succesfully initialized and Err, if it was already initialized before
29//!
30//! ## Usage Example
31//!
32//! ```
33//! init_guard!(HAS_LOGGER_INIT); // Create the init_guard
34//!
35//! fn init_logger() -> Result<(),String> {
36//! match HAS_LOGGER_INIT::init() {
37//! Ok(_) => {},
38//! Err(_) => {return Err("Logger is already initialized!".to_string())}
39//! }
40//! // Everything after this is now safe from double initialization
41//!
42//! // Do your actual logger initialization here
43//! }
44//! ```
45
46#[allow(unused_imports)]
47#[macro_use]
48extern crate lazy_static;
49use lazy_static::lazy_static;
50
51#[macro_export]
52macro_rules! init_guard {
53 ($global_vis:vis $global_name:ident) => {
54 $global_vis mod $global_name {
55 use std::sync::{Mutex, Once};
56 lazy_static! {
57 static ref MUTEX_ONCE: Mutex<Once> = Mutex::<Once>::new(Once::new());
58 }
59
60 pub fn has_init() -> bool {
61 let once = MUTEX_ONCE.lock().unwrap();
62 return once.is_completed();
63 }
64
65 pub fn init() -> Result<(),()> {
66 let once = MUTEX_ONCE.lock().unwrap();
67 if once.is_completed() {return Err(()); }
68
69 once.call_once(|| {});
70 Ok(())
71 }
72 }
73 }
74}