Bläddra i källkod

put the `tokio` feature into a separate module.

ZRY 1 år sedan
förälder
incheckning
3554297547
3 ändrade filer med 129 tillägg och 41 borttagningar
  1. 6 2
      Cargo.toml
  2. 14 39
      src/lib.rs
  3. 109 0
      src/tokio/mod.rs

+ 6 - 2
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "simple-rw-global"
-version = "0.2.1"
+version = "0.3.0"
 edition = "2021"
 authors = ["ZRY <admin@>z-touhou.org"]
 
@@ -16,4 +16,8 @@ stdsync=[]
 tokio=["dep:tokio"]
 
 [dependencies]
-tokio = { version="1.28.0", optional=true, features=["sync"] }
+tokio = { version="1.28.0", optional=true, features=["sync"] }
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]

+ 14 - 39
src/lib.rs

@@ -1,3 +1,4 @@
+#![cfg_attr(docsrs, feature(doc_cfg))]
 //! Simple GlobalContainer based on std::sync::RwLock.
 //!
 //! This crate is AS IS.
@@ -12,13 +13,12 @@
 //!
 //! ```toml
 //! [dependency]
-//! simple-rw-global = { version="0.2.0", default-features = false, feature=["tokio"] }
+//! simple-rw-global = { version="0.3.0", feature=["tokio"] }
 //! ```
 //!
-//! With this feature, `lazy_static!` should be used for `GlobalContainer::new()`,
-//! because of `tokio::sync::RwLock::new()` is not a constant function.
+//! With this feature, module `tokio` is available.
 //!
-//! # Example:
+//! # Example
 //!
 //! ```
 //! use simple_rw_global::GlobalContainer;
@@ -60,14 +60,14 @@
 //!
 //!
 
+
+#[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};
-#[cfg(feature = "tokio")]
-use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
-
-#[cfg(all(feature = "stdsync", feature = "tokio"))]
-compile_error!("feature \"std\" and feature \"tokio\" cannot be enabled at the same time");
 
 pub enum GOption<T> {
     None,
@@ -95,6 +95,7 @@ impl<T> DerefMut for GOption<T> {
     }
 }
 
+#[cfg(feature = "stdsync")]
 pub struct GlobalContainer<T>
 {
     content: RwLock<GOption<T>>,
@@ -133,35 +134,9 @@ impl<T> GlobalContainer<T> {
     }
 }
 
-#[cfg(feature = "tokio")]
-impl<T> GlobalContainer<T> {
-    pub fn new() -> GlobalContainer<T> {
-        GlobalContainer::<T>{
-            content: RwLock::new(GOption::None),
-        }
-    }
-
-    pub async fn set(&self, obj: T) {
-        *self.content.write().await = GOption::Some(obj);
-    }
-
-    pub async fn is_empty(&self) -> bool {
-        let v = self.content.read().await;
-        match v.deref() {
-            GOption::None => true,
-            GOption::Some(_) => false,
-        }
-    }
-
-    pub async fn manual_drop(&self) {
-        *self.content.write().await = GOption::None;
-    }
-
-    pub async fn get(&self) -> RwLockReadGuard<GOption<T>> {
-        self.content.read().await
-    }
-
-    pub async fn get_mut(&self) -> RwLockWriteGuard<GOption<T>> {
-        self.content.write().await
+#[cfg(feature = "stdsync")]
+impl<T> Drop for GlobalContainer<T> {
+    fn drop(&mut self) {
+        self.manual_drop();
     }
 }

+ 109 - 0
src/tokio/mod.rs

@@ -0,0 +1,109 @@
+//! Async version for `tokio`, need feature `tokio`.
+//!
+//! `lazy_static!` should be used for `AsyncGlobalContainer::new()`,
+//! because of `tokio::sync::RwLock::new()` is not a constant function.
+//!
+//! # Example
+//!
+//! ```rust
+//!
+//! use std::time::Duration;
+//! use lazy_static::lazy_static;
+//! use simple_rw_global::tokio::AsyncGlobalContainer;
+//! use tokio::task::JoinSet;
+//!
+//! lazy_static! {
+//!     static ref GLOBAL : AsyncGlobalContainer<GlobalObject> = AsyncGlobalContainer::<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);
+//!     }
+//! }
+//!
+//! #[tokio::main]
+//! async fn main() {
+//!     println!("before init, is empty: {}", GLOBAL.is_empty().await);
+//!     GLOBAL.set(GlobalObject::new("log-test1")).await;
+//!     println!("after init, is empty: {}", GLOBAL.is_empty().await);
+//!     println!("init ok.");
+//!
+//!     let mut task_set = JoinSet::new();
+//!     task_set.spawn(async {
+//!         loop {
+//!             GLOBAL.get().await.log("task1");
+//!             tokio::time::sleep(Duration::from_millis(500)).await;
+//!         }
+//!     });
+//!
+//!     task_set.spawn(async {
+//!         loop {
+//!             GLOBAL.get().await.log("task2");
+//!             tokio::time::sleep(Duration::from_millis(500)).await;
+//!         }
+//!     });
+//!
+//!     task_set.join_next().await;
+//!     println!("Program is quitting, aborting all task...");
+//!     task_set.abort_all();
+//!     println!("Program quit.");
+//! }
+//! ```
+
+use std::ops::Deref;
+#[cfg(feature = "tokio")]
+use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
+use crate::GOption;
+
+
+#[cfg(feature = "tokio")]
+pub struct AsyncGlobalContainer<T>
+{
+    content: RwLock<GOption<T>>,
+}
+
+#[cfg(feature = "tokio")]
+impl<T> AsyncGlobalContainer<T> {
+    pub fn new() -> AsyncGlobalContainer<T> {
+        AsyncGlobalContainer::<T>{
+            content: RwLock::new(GOption::None),
+        }
+    }
+
+    pub async fn set(&self, obj: T) {
+        *self.content.write().await = GOption::Some(obj);
+    }
+
+    pub async fn is_empty(&self) -> bool {
+        let v = self.content.read().await;
+        match v.deref() {
+            GOption::None => true,
+            GOption::Some(_) => false,
+        }
+    }
+
+    pub async fn manual_drop(&self) {
+        *self.content.write().await = GOption::None;
+    }
+
+    pub async fn get(&self) -> RwLockReadGuard<GOption<T>> {
+        self.content.read().await
+    }
+
+    pub async fn get_mut(&self) -> RwLockWriteGuard<GOption<T>> {
+        self.content.write().await
+    }
+}