123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #![cfg_attr(docsrs, feature(doc_cfg))]
- //! Simple GlobalContainer based on std::sync::RwLock.
- //!
- //! This crate is AS IS.
- //!
- //! NOTE: `GlobalContainer` use `RWLock`, `GlobalMutexContainer` use `Mutex`.
- //!
- //! By ZRY.
- //!
- //! # Features
- //!
- //! ## `tokio`
- //!
- //! For tokio, use feature `tokio`
- //!
- //! ```toml
- //! [dependency]
- //! simple-rw-global = { version="0.3.0", feature=["tokio"] }
- //! ```
- //!
- //! With this feature, module `tokio` is available.
- //!
- //! # Example
- //!
- //! ```
- //! use simple_rw_global::GlobalContainer;
- //!
- //! static GLOBAL : GlobalContainer<GlobalObject> = GlobalContainer::<GlobalObject>::new();
- //!
- //! pub struct GlobalObject {
- //! log_prefix: String,
- //! }
- //!
- //! impl GlobalObject {
- //! pub fn new(prefix: &str) -> GlobalObject {
- //! GlobalObject{log_prefix: String::from(prefix)}
- //! }
- //!
- //! pub fn log(&self, msg: &str) {
- //! println!("[{}] {}", self.log_prefix.as_str(), msg);
- //! }
- //!
- //! pub fn change_prefix(&mut self, prefix: &str) {
- //! self.log_prefix = String::from(prefix);
- //! }
- //! }
- //!
- //! fn main() {
- //! println!("before init, is empty: {}", GLOBAL.is_empty());
- //! GLOBAL.set(GlobalObject::new("log-test1"));
- //! println!("after init, is empty: {}", GLOBAL.is_empty());
- //! println!("init ok.");
- //! GLOBAL.get().log("hello 1");
- //! GLOBAL.get_mut().change_prefix("log-test2");
- //! GLOBAL.get().log("hello 2");
- //! GLOBAL.manual_drop();
- //! println!("dropped manually. will panic then.");
- //! GLOBAL.get().log("test after drop.");
- //! }
- //!
- //! ```
- //!
- //!
- #[cfg(feature = "tokio")]
- #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
- pub mod tokio;
- use std::ops::{Deref, DerefMut};
- #[cfg(feature = "stdsync")]
- use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, Mutex, MutexGuard};
- pub enum GOption<T> {
- None,
- Some(T)
- }
- impl<T> Deref for GOption<T> {
- type Target = T;
- fn deref(&self) -> &Self::Target {
- match self {
- GOption::None => { panic!("operate on empty GlobalContainer"); },
- GOption::Some(t) => t,
- }
- }
- }
- impl<T> DerefMut for GOption<T> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- match self {
- GOption::None => { panic!("operate on empty GlobalContainer"); },
- GOption::Some(t) => t,
- }
- }
- }
- #[cfg(feature = "stdsync")]
- pub struct GlobalContainer<T>
- {
- content: RwLock<GOption<T>>,
- }
- #[cfg(feature = "stdsync")]
- impl<T> GlobalContainer<T> {
- pub const fn new() -> GlobalContainer<T> {
- GlobalContainer::<T>{
- content: RwLock::new(GOption::None),
- }
- }
- pub fn set(&self, obj: T) {
- *self.content.write().unwrap() = GOption::Some(obj);
- }
- pub fn is_empty(&self) -> bool {
- let v = self.content.read().unwrap();
- match v.deref() {
- GOption::None => true,
- GOption::Some(_) => false,
- }
- }
- pub fn manual_drop(&self) {
- *self.content.write().unwrap() = GOption::None;
- }
- pub fn get(&self) -> RwLockReadGuard<GOption<T>> {
- self.content.read().unwrap()
- }
- pub fn get_mut(&self) -> RwLockWriteGuard<GOption<T>> {
- self.content.write().unwrap()
- }
- }
- #[cfg(feature = "stdsync")]
- impl<T> Drop for GlobalContainer<T> {
- fn drop(&mut self) {
- self.manual_drop();
- }
- }
- #[cfg(feature = "stdsync")]
- pub struct GlobalMutexContainer<T>
- {
- content: Mutex<GOption<T>>,
- }
- #[cfg(feature = "stdsync")]
- impl<T> GlobalMutexContainer<T> {
- pub const fn new() -> GlobalMutexContainer<T> {
- GlobalMutexContainer::<T>{
- content: Mutex::new(GOption::None),
- }
- }
- pub fn set(&self, obj: T) {
- *self.content.lock().unwrap() = GOption::Some(obj);
- }
- pub fn is_empty(&self) -> bool {
- let v = self.content.lock().unwrap();
- match v.deref() {
- GOption::None => true,
- GOption::Some(_) => false,
- }
- }
- pub fn manual_drop(&self) {
- *self.content.lock().unwrap() = GOption::None;
- }
- pub fn get(&self) -> MutexGuard<GOption<T>> {
- self.content.lock().unwrap()
- }
- pub fn get_mut(&self) -> MutexGuard<GOption<T>> {
- self.content.lock().unwrap()
- }
- }
- #[cfg(feature = "stdsync")]
- impl<T> Drop for GlobalMutexContainer<T> {
- fn drop(&mut self) {
- self.manual_drop();
- }
- }
|