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
83
84
85
86
87
88
89
90
91
92
/** `Internal variability` for [`Lazystatic`](https://crates.io/crates/lazy_static)

## Example:

### On Cargo.toml:
```toml
lazy_static = "^0.2.8"
stderr = "0.8.0" 
```

### On Code:
```rust
#[macro_use]
extern crate lazy_static;
extern crate stderr;
use stderr::StaticMut;

lazy_static!{
    static ref STRING : StaticMut<String> = StaticMut::new(String::new());
    static ref USIZE : StaticMut<Usize> = StaticMut::new(Usize(0));
}

fn main() {
    // Before write, You can read it Concurrent safely.
    println!("{:?}", STRING.as_ref());
    println!("{:?}", USIZE.as_ref());

    let str = {
        let mut str = "StaticMut, 雪之下".to_string();
        // do some work
        str
    };
    // But when write it, operate it Concurrent is unsafe.
    {
        STRING.set(str); // update by setting value
        USIZE.as_mut().0 = 123; // update by modifying field
    }

    // After write, You can read it Concurrent safely.
    println!("{:?}", STRING.as_ref());
    println!("{:?}", USIZE.as_ref());
}

#[derive(Debug)]
struct Usize(usize);

```

## About safe and unsafe 

If you read or write it when you write it, I don't ensure anything.

You can add `AtomicXXX` to ensure safe on above situation also.

If you need full Concurrent read and write, you maybe need `RwLock`
*/
#[derive(Debug)]
pub struct StaticMut<T>(UnsafeCell<T>);

use std::marker::Sync;
use std::cell::UnsafeCell;
unsafe impl<T> Sync for StaticMut<T> {}

impl<T> StaticMut<T> {
    #[inline]    
    pub fn new(value: T) -> Self {
        StaticMut(UnsafeCell::new(value))
    }
    /// read it
    #[inline]
    #[allow(unknown_lints,should_implement_trait)]
    pub fn as_ref(&self) -> &T {
        unsafe { self.0.get().as_ref().unwrap() }
    }
    /// write it
    #[allow(unknown_lints,mut_from_ref)]
    #[inline]
    pub fn as_mut(&self) -> &mut T {
        unsafe { self.0.get().as_mut().unwrap() }
    }
    /// update it
    #[inline]
    pub fn set(&self, value:T) {
        *self.as_mut() = value
    }
    ///Unwraps the value
    #[inline]
    pub fn into_inner(self)->T {
        unsafe {self.0.into_inner()}
    }
}