weak_static/
lib.rs

1//! This crate provides a macro to create a static value that gets created when needed
2//! and dropped as soon as its not needed anymore.
3//! It requires the `lazy_static` macro to be imported.
4//!
5//! # Example
6//!
7//! ```rust
8//! #[macro_use] extern crate lazy_static;
9//! #[macro_use] extern crate weak_static;
10//! 
11//! struct Foo;
12//!
13//! impl Foo {
14//!     fn new() -> Self {
15//!         println!("new");
16//!         Foo
17//!     }
18//! }
19//!
20//! impl Drop for Foo {
21//!     fn drop(&mut self) {
22//!         println!("drop");
23//!     }
24//! }
25//! 
26//! weak_static! {
27//!     static FOO: Foo = Foo::new();
28//! }
29//!
30//! fn main() {
31//!     {
32//!         let _foo1 = FOO();
33//!         let _foo2 = FOO();
34//!         let _foo3 = FOO();
35//!     }
36//!     
37//!     {
38//!         let _foo4 = FOO();
39//!         let _foo5 = FOO();
40//!         let _foo6 = FOO();
41//!     }
42//! }
43//! ```
44//!
45//! Outputs:
46//!
47//! ```text
48//! new
49//! drop
50//! new
51//! drop
52//! ```
53//!
54//! The `new` prints corresponds to the `FOO()` calls of `_foo1` and `_foo4`.
55//! The `drop` prints correspond to the last FOO reference being dropped.
56//!
57
58#[macro_export]
59macro_rules! weak_static {
60    (static $ident:ident : $typ:ty = $init:expr; ) => (
61        #[allow(non_snake_case)]
62        fn $ident() -> ::std::sync::Arc<$typ> {
63            #[warn(non_snake_case)]
64            {
65                lazy_static! {
66                    static ref VALUE: ::std::sync::Mutex<::std::sync::Weak<$typ>> =
67                        ::std::default::Default::default();
68                }
69                
70                let mut value = VALUE.lock().unwrap();
71                
72                value.upgrade().unwrap_or_else(|| {
73                    let new_value = ::std::sync::Arc::new($init);
74
75                    *value = ::std::sync::Arc::downgrade(&new_value);
76                    
77                    new_value
78                })
79            }
80        }
81    )
82}