diff --git a/Cargo.lock b/Cargo.lock index 451416e..5627349 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,6 +395,7 @@ dependencies = [ "generational-arena", "lazy_static", "libc", + "mopa", "notify", "once_cell", "recolored", @@ -461,6 +462,12 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "mopa" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915" + [[package]] name = "net2" version = "0.2.34" diff --git a/Cargo.toml b/Cargo.toml index a0803da..afdcb20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ chrono = "0.4" libc = "0.2" cfg-if = "0.1" generational-arena = "0.2" +mopa = "0.2" [build-dependencies] rustc_version = "0.2" diff --git a/build.rs b/build.rs index c7d2ac8..cd37d0d 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,3 @@ - extern crate rustc_version; use rustc_version::{version, version_meta, Channel}; diff --git a/src/log/custom.rs b/src/log/custom.rs index 266ffa5..c833836 100644 --- a/src/log/custom.rs +++ b/src/log/custom.rs @@ -1,11 +1,12 @@ //! Extra logging types for log files and such use super::*; use generational_arena::Index; +use mopa::*; use std::marker::{Sync, Send}; /// A logging hook -pub trait Hook: Sync + Send +pub trait Hook: Sync + Send + Any { /// The name of this hook object fn name(&self) -> &str {"(unnamed)"} @@ -16,6 +17,7 @@ pub trait Hook: Sync + Send /// Fired when hook is removed fn finalise(&mut self, _idx: Index) {} } +mopafy!(Hook); impl std::fmt::Debug for dyn Hook { diff --git a/src/log/mod.rs b/src/log/mod.rs index b91064a..b588966 100644 --- a/src/log/mod.rs +++ b/src/log/mod.rs @@ -97,7 +97,7 @@ impl Logger idx } - /// Try to remove and return a logging hook. + /// Try to remove and return the removed logging hook. /// /// # Returns /// `None` if `hook` is not present or its `RwLock` was poisoned, otherwise, returns boxed trait object of the hook. @@ -114,6 +114,53 @@ impl Logger .flatten() } + /// Try to remove, downcast, and return the removed logging hook. Assume the downcasting will not fail. + /// + /// # Returns + /// `None` if [remove_hook]`remove_hook` returns `None`, `Some(H)` if it is removed successfully **and also** downcasted successfully. + /// + /// Function will also return `None` if removal was successful but downcasting was not. + /// + /// If this it not desireable, check [remove_hook_try_downcasted]`remove_hook_try_downcasted`. + pub fn remove_hook_assume_downcasted>(&self, hook: I) -> Option + { + if let Some(bx) = self.remove_hook(hook) { + bx.downcast().ok().map(|x| *x) + } else { + None + } + } + + /// Remove, downcast, and return the removed logging hook. + /// + /// # Returns + /// `None` if [remove_hook]`remove_hook` returns `None`, `Some(H)` if it is removed successfully **and also** downcasted successfully. + /// + /// # Panics + /// + /// If downcasting fails + pub fn remove_hook_downcasted>(&self, hook: I) -> Option + { + if let Some(bx) = self.remove_hook(hook) { + Some(*bx.downcast().expect("Downcast failed on removed hook")) + } else { + None + } + } + + /// Try to remove, downcast, and return the removed logging hook. + /// + /// # Returns + /// `Err(false)` if [remove_hook]`remove_hook` returns `None`, `Ok(H)` if it is removed successfully **and also** downcasted successfully. `Err(true)` if removal was successful but not downcasting. + pub fn remove_hook_try_downcasted>(&self, hook: I) -> Result + { + if let Some(bx) = self.remove_hook(hook) { + bx.downcast().map_err(|_| true).map(|x| *x) + } else { + Err(false) + } + } + /// Print a line to this logger. /// You should usually print using the macros defined here instead of calling this directly. pub fn println(&self, mut to: W, level: L, what: D, trace: T) -> io::Result<()> diff --git a/src/main.rs b/src/main.rs index 870006c..537fd4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,7 +127,7 @@ async fn main() -> Result<(), Box> { debug!("Logger initialised"); //TODO: Parse config first print_stats(); - debug!("{:?}",sys::user::get_users()); + //debug!("{:?}",sys::user::get_users()); #[cfg(feature="watcher")] {