From 475085247fd8d9d445a2f3a8561348a2765110ee Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sat, 30 Sep 2023 10:53:07 +0200 Subject: [PATCH 1/2] Make equality works on noop callbacks of same type --- packages/yew/src/callback.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index 1ba61d9de74..c6db179d1cc 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -4,6 +4,9 @@ //! - [Counter](https://github.com/yewstack/yew/tree/master/examples/counter) //! - [Timer](https://github.com/yewstack/yew/tree/master/examples/timer) +use std::any; +use std::cell::RefCell; +use std::collections::HashMap; use std::fmt; use std::rc::Rc; @@ -33,6 +36,8 @@ macro_rules! generate_callback_impls { } } + impl Eq for $callback {} + impl fmt::Debug for $callback { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "$callback<_>") @@ -46,15 +51,31 @@ macro_rules! generate_callback_impls { } } - impl $callback { + impl $callback { /// Creates a "no-op" callback which can be used when it is not suitable to use an /// `Option<$callback>`. pub fn noop() -> Self { - Self::from(|_: $in_ty| ()) + thread_local! { + static NOOP: RefCell>> = RefCell::new(Default::default()); + } + + Self { + cb: NOOP.with(|noop| { + noop.borrow_mut() + .entry(any::TypeId::of::<$in_ty>()) + .or_insert_with(|| { + let func: Rc ()> = Rc::new(|_: $in_ty| ()); + Box::new(func) as Box + }) + .downcast_ref:: ()>>() + .unwrap() + .clone() + }), + } } } - impl Default for $callback { + impl Default for $callback { fn default() -> Self { Self::noop() } @@ -300,4 +321,9 @@ mod test { reformed.emit(&mut value).expect("is some"); assert_eq!(value, 45); } + + #[test] + fn test_noop_eq() { + assert_eq!(Callback::::noop(), Callback::::noop()); + } } From 28fc872f492c462059082f7c266f9bdbdaaef17b Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sat, 30 Sep 2023 11:02:38 +0200 Subject: [PATCH 2/2] CLEANUP --- packages/yew/src/callback.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index c6db179d1cc..814d65b5b7b 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -4,11 +4,10 @@ //! - [Counter](https://github.com/yewstack/yew/tree/master/examples/counter) //! - [Timer](https://github.com/yewstack/yew/tree/master/examples/timer) -use std::any; use std::cell::RefCell; use std::collections::HashMap; -use std::fmt; use std::rc::Rc; +use std::{any, fmt}; use crate::html::ImplicitClone; @@ -64,10 +63,10 @@ macro_rules! generate_callback_impls { noop.borrow_mut() .entry(any::TypeId::of::<$in_ty>()) .or_insert_with(|| { - let func: Rc ()> = Rc::new(|_: $in_ty| ()); + let func: Rc = Rc::new(|_: $in_ty| ()); Box::new(func) as Box }) - .downcast_ref:: ()>>() + .downcast_ref::>() .unwrap() .clone() }), @@ -325,5 +324,7 @@ mod test { #[test] fn test_noop_eq() { assert_eq!(Callback::::noop(), Callback::::noop()); + assert_eq!(CallbackRef::::noop(), CallbackRef::::noop()); + assert_eq!(CallbackRefMut::::noop(), CallbackRefMut::::noop()); } }