1#![cfg_attr(docsrs, feature(doc_cfg))]
2#[cfg(feature = "tokio")]
67#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
68pub mod tokio;
69
70use std::ops::{Deref, DerefMut};
71#[cfg(feature = "stdsync")]
72use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, Mutex, MutexGuard};
73
74pub enum GOption<T> {
75 None,
76 Some(T)
77}
78
79impl<T> Deref for GOption<T> {
80 type Target = T;
81
82 fn deref(&self) -> &Self::Target {
83 match self {
84 GOption::None => { panic!("operate on empty GlobalContainer"); },
85 GOption::Some(t) => t,
86 }
87 }
88}
89
90impl<T> DerefMut for GOption<T> {
91
92 fn deref_mut(&mut self) -> &mut Self::Target {
93 match self {
94 GOption::None => { panic!("operate on empty GlobalContainer"); },
95 GOption::Some(t) => t,
96 }
97 }
98}
99
100#[cfg(feature = "stdsync")]
101pub struct GlobalContainer<T>
102{
103 content: RwLock<GOption<T>>,
104}
105
106#[cfg(feature = "stdsync")]
107impl<T> GlobalContainer<T> {
108 pub const fn new() -> GlobalContainer<T> {
109 GlobalContainer::<T>{
110 content: RwLock::new(GOption::None),
111 }
112 }
113
114 pub fn set(&self, obj: T) {
115 *self.content.write().unwrap() = GOption::Some(obj);
116 }
117
118 pub fn is_empty(&self) -> bool {
119 let v = self.content.read().unwrap();
120 match v.deref() {
121 GOption::None => true,
122 GOption::Some(_) => false,
123 }
124 }
125
126 pub fn manual_drop(&self) {
127 *self.content.write().unwrap() = GOption::None;
128 }
129
130 pub fn get(&self) -> RwLockReadGuard<GOption<T>> {
131 self.content.read().unwrap()
132 }
133
134 pub fn get_mut(&self) -> RwLockWriteGuard<GOption<T>> {
135 self.content.write().unwrap()
136 }
137}
138
139#[cfg(feature = "stdsync")]
140impl<T> Drop for GlobalContainer<T> {
141 fn drop(&mut self) {
142 self.manual_drop();
143 }
144}
145
146#[cfg(feature = "stdsync")]
147pub struct GlobalMutexContainer<T>
148{
149 content: Mutex<GOption<T>>,
150}
151
152#[cfg(feature = "stdsync")]
153impl<T> GlobalMutexContainer<T> {
154 pub const fn new() -> GlobalMutexContainer<T> {
155 GlobalMutexContainer::<T>{
156 content: Mutex::new(GOption::None),
157 }
158 }
159
160 pub fn set(&self, obj: T) {
161 *self.content.lock().unwrap() = GOption::Some(obj);
162 }
163
164 pub fn is_empty(&self) -> bool {
165 let v = self.content.lock().unwrap();
166 match v.deref() {
167 GOption::None => true,
168 GOption::Some(_) => false,
169 }
170 }
171
172 pub fn manual_drop(&self) {
173 *self.content.lock().unwrap() = GOption::None;
174 }
175
176 pub fn get(&self) -> MutexGuard<GOption<T>> {
177 self.content.lock().unwrap()
178 }
179
180 pub fn get_mut(&self) -> MutexGuard<GOption<T>> {
181 self.content.lock().unwrap()
182 }
183}
184
185#[cfg(feature = "stdsync")]
186impl<T> Drop for GlobalMutexContainer<T> {
187 fn drop(&mut self) {
188 self.manual_drop();
189 }
190}