diff --git a/CHANGELOG.md b/CHANGELOG.md index c542568..2252b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Breaking Changes + +- `Source::for_each_*` now invoke the callback with the current contents of of + the source before attaching the callback. New functions beginning with + `for_each_subsequent_` have been added with the original behavior. + ### Fixed - Fixed a panic that could occur when removing certain nested hierarchies from a window. +- `CallbackHandle` now has a `must_use` hint that might help users discover the + persist function. ### Added diff --git a/src/value.rs b/src/value.rs index 4d2a714..9a7d2b1 100644 --- a/src/value.rs +++ b/src/value.rs @@ -132,19 +132,83 @@ pub trait Source { } /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// source's contents are updated. + /// + /// `for_each` will not be invoked with the currently stored value. /// /// Returning `Err(CallbackDisconnected)` will prevent the callback from /// being invoked again. - fn for_each_generational_try(&self, for_each: F) -> CallbackHandle + fn for_each_subsequent_generational_try(&self, for_each: F) -> CallbackHandle where T: Send + 'static, F: for<'a> FnMut(DynamicGuard<'_, T, true>) -> Result<(), CallbackDisconnected> + Send + 'static; - /// Attaches `for_each` to this value and its [`Generation`] so that it is - /// invoked each time the value's contents are updated. + /// Attaches `for_each` to this value so that it is invoked each time the + /// source's contents are updated. + /// + /// `for_each` will not be invoked with the currently stored value. + fn for_each_subsequent_generational(&self, mut for_each: F) -> CallbackHandle + where + T: Send + 'static, + F: for<'a> FnMut(DynamicGuard<'_, T, true>) + Send + 'static, + { + self.for_each_subsequent_generational_try(move |value| { + for_each(value); + Ok(()) + }) + } + + /// Attaches `for_each` to this value so that it is invoked each time the + /// source's contents are updated. + /// + /// `for_each` will not be invoked with the currently stored value. + /// + /// Returning `Err(CallbackDisconnected)` will prevent the callback from + /// being invoked again. + fn for_each_subsequent_try(&self, mut for_each: F) -> CallbackHandle + where + T: Send + 'static, + F: for<'a> FnMut(&'a T) -> Result<(), CallbackDisconnected> + Send + 'static, + { + self.for_each_subsequent_generational_try(move |gen| for_each(&*gen)) + } + + /// Attaches `for_each` to this value so that it is invoked each time the + /// source's contents are updated. + /// + /// `for_each` will not be invoked with the currently stored value. + fn for_each_subsequent(&self, mut for_each: F) -> CallbackHandle + where + T: Send + 'static, + F: for<'a> FnMut(&'a T) + Send + 'static, + { + self.for_each_subsequent_try(move |value| { + for_each(value); + Ok(()) + }) + } + + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. + /// + /// Returning `Err(CallbackDisconnected)` will prevent the callback from + /// being invoked again. + fn for_each_generational_try(&self, mut for_each: F) -> CallbackHandle + where + T: Send + 'static, + F: for<'a> FnMut(DynamicGuard<'_, T, true>) -> Result<(), CallbackDisconnected> + + Send + + 'static, + { + self.map_generational(&mut for_each) + .expect("initial for_each invocation failed"); + self.for_each_subsequent_generational_try(for_each) + } + + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. fn for_each_generational(&self, mut for_each: F) -> CallbackHandle where T: Send + 'static, @@ -156,8 +220,8 @@ pub trait Source { }) } - /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. /// /// Returning `Err(CallbackDisconnected)` will prevent the callback from /// being invoked again. @@ -169,8 +233,8 @@ pub trait Source { self.for_each_generational_try(move |gen| for_each(&*gen)) } - /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. fn for_each(&self, mut for_each: F) -> CallbackHandle where T: Send + 'static, @@ -182,8 +246,8 @@ pub trait Source { }) } - /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. /// /// Returning `Err(CallbackDisconnected)` will prevent the callback from /// being invoked again. @@ -192,8 +256,8 @@ pub trait Source { T: Clone + Send + 'static, F: FnMut(GenerationalValue) -> Result<(), CallbackDisconnected> + Send + 'static; - /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. fn for_each_cloned_try(&self, mut for_each: F) -> CallbackHandle where T: Clone + Send + 'static, @@ -202,8 +266,8 @@ pub trait Source { self.for_each_generational_cloned_try(move |gen| for_each(gen.value)) } - /// Attaches `for_each` to this value so that it is invoked each time the - /// value's contents are updated. + /// Invokes `for_each` with the current contents and each time this source's + /// contents are updated. fn for_each_cloned(&self, mut for_each: F) -> CallbackHandle where T: Clone + Send + 'static, @@ -531,7 +595,7 @@ impl Source for Arc> { })) } - fn for_each_generational_try(&self, mut for_each: F) -> CallbackHandle + fn for_each_subsequent_generational_try(&self, mut for_each: F) -> CallbackHandle where T: Send + 'static, F: for<'a> FnMut(DynamicGuard<'a, T, true>) -> Result<(), CallbackDisconnected> @@ -572,14 +636,14 @@ impl Source for Dynamic { self.0.try_map_generational(map) } - fn for_each_generational_try(&self, for_each: F) -> CallbackHandle + fn for_each_subsequent_generational_try(&self, for_each: F) -> CallbackHandle where T: Send + 'static, F: for<'a> FnMut(DynamicGuard<'_, T, true>) -> Result<(), CallbackDisconnected> + Send + 'static, { - self.0.for_each_generational_try(for_each) + self.0.for_each_subsequent_generational_try(for_each) } fn for_each_generational_cloned_try(&self, for_each: F) -> CallbackHandle @@ -602,14 +666,14 @@ impl Source for DynamicReader { }) } - fn for_each_generational_try(&self, for_each: F) -> CallbackHandle + fn for_each_subsequent_generational_try(&self, for_each: F) -> CallbackHandle where T: Send + 'static, F: for<'a> FnMut(DynamicGuard<'_, T, true>) -> Result<(), CallbackDisconnected> + Send + 'static, { - self.source.for_each_generational_try(for_each) + self.source.for_each_subsequent_generational_try(for_each) } fn for_each_generational_cloned_try(&self, for_each: F) -> CallbackHandle @@ -749,7 +813,7 @@ impl Source for Owned { })) } - fn for_each_generational_try(&self, for_each: F) -> CallbackHandle + fn for_each_subsequent_generational_try(&self, for_each: F) -> CallbackHandle where T: Send + 'static, F: for<'a> FnMut(DynamicGuard<'a, T, true>) -> Result<(), CallbackDisconnected> @@ -1537,7 +1601,7 @@ trait CallbackCollection: Send + Sync + 'static { /// /// To prevent the callback from ever being uninstalled, use /// [`Self::persist()`]. -#[must_use] +#[must_use = "Callbacks are disconnected once the associated CallbackHandle is dropped. Consider using `CallbackHandle::persist()` to prevent the callback from being disconnected."] pub struct CallbackHandle(CallbackHandleInner); impl Default for CallbackHandle {