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