Skip to content

Commit

Permalink
impl Dispose for Callback types and add try_run to the Callable trait
Browse files Browse the repository at this point in the history
  • Loading branch information
basro committed Dec 16, 2024
1 parent 6b50179 commit 157b72c
Showing 1 changed file with 49 additions and 4 deletions.
53 changes: 49 additions & 4 deletions leptos/src/callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,20 @@
use reactive_graph::{
owner::{LocalStorage, StoredValue},
traits::WithValue,
traits::{Dispose, WithValue},
};
use std::{fmt, rc::Rc, sync::Arc};

/// A wrapper trait for calling callbacks.
pub trait Callable<In: 'static, Out: 'static = ()> {
/// calls the callback with the specified argument.
///
/// Returns None if the callback has been disposed
fn try_run(&self, input: In) -> Option<Out>;
/// calls the callback with the specified argument.
///
/// # Panics
/// Panics if you try to run a callback that has been disposed
fn run(&self, input: In) -> Out;
}

Expand All @@ -72,6 +79,12 @@ impl<In, Out> Clone for UnsyncCallback<In, Out> {
}
}

impl<In, Out> Dispose for UnsyncCallback<In, Out> {
fn dispose(self) {
self.0.dispose();
}
}

impl<In, Out> UnsyncCallback<In, Out> {
/// Creates a new callback from the given function.
pub fn new<F>(f: F) -> UnsyncCallback<In, Out>
Expand All @@ -83,6 +96,10 @@ impl<In, Out> UnsyncCallback<In, Out> {
}

impl<In: 'static, Out: 'static> Callable<In, Out> for UnsyncCallback<In, Out> {
fn try_run(&self, input: In) -> Option<Out> {
self.0.try_with_value(|fun| fun(input))
}

fn run(&self, input: In) -> Out {
self.0.with_value(|fun| fun(input))
}
Expand Down Expand Up @@ -158,10 +175,12 @@ impl<In, Out> fmt::Debug for Callback<In, Out> {
}

impl<In, Out> Callable<In, Out> for Callback<In, Out> {
fn try_run(&self, input: In) -> Option<Out> {
self.0.try_with_value(|fun| fun(input))
}

fn run(&self, input: In) -> Out {
self.0
.try_with_value(|f| f(input))
.expect("called a callback that has been disposed")
self.0.with_value(|f| f(input))
}
}

Expand All @@ -171,6 +190,12 @@ impl<In, Out> Clone for Callback<In, Out> {
}
}

impl<In, Out> Dispose for Callback<In, Out> {
fn dispose(self) {
self.0.dispose();
}
}

impl<In, Out> Copy for Callback<In, Out> {}

macro_rules! impl_callable_from_fn {
Expand Down Expand Up @@ -216,8 +241,12 @@ impl<In: 'static, Out: 'static> Callback<In, Out> {

#[cfg(test)]
mod tests {
use reactive_graph::traits::Dispose;

use crate::callback::{Callback, UnsyncCallback};

use super::Callable;

struct NoClone {}

#[test]
Expand Down Expand Up @@ -246,4 +275,20 @@ mod tests {
let _callback: UnsyncCallback<(i32, String), String> =
(|num, s| format!("{num} {s}")).into();
}

#[test]
fn sync_callback_try_run() {
let callback = Callback::new(move |arg| arg);
assert_eq!(callback.try_run((0,)), Some((0,)));
callback.dispose();
assert_eq!(callback.try_run((0,)), None);
}

#[test]
fn unsync_callback_try_run() {
let callback = UnsyncCallback::new(move |arg| arg);
assert_eq!(callback.try_run((0,)), Some((0,)));
callback.dispose();
assert_eq!(callback.try_run((0,)), None);
}
}

0 comments on commit 157b72c

Please sign in to comment.