Best way to "wrap" a signal? #1684
-
Hello, I'm trying to create a "custom signal" in order to have some custom methods. I wrap a First, do I need to implement I saw a discussion about a macro to create signal (see #1233) but while waiting for it, how can I wrap a signal and keep my struct reactive? Thanks in advance for any help! Below is the custom signal I implemented, it represents an "opening" signal for some modals and it gives some helpers to toggle the opening state. When I call use leptos::{
create_rw_signal,
ReadSignal,
RwSignal,
SignalGet,
SignalSet,
SignalUpdate,
SignalWith,
};
pub struct OpenedSignal(RwSignal<bool>);
impl OpenedSignal {
pub fn new(initial_status: bool) -> Self {
Self(create_rw_signal(initial_status))
}
pub fn new_closed() -> Self {
Self::new(false)
}
pub fn new_opened() -> Self {
Self::new(true)
}
pub fn toggle(&self) {
self.0.set(self.0());
}
pub fn open(&self) {
self.0.set(true);
}
pub fn close(&self) {
self.0.set(true);
}
}
impl Clone for OpenedSignal {
fn clone(&self) -> Self {
*self
}
}
impl Copy for OpenedSignal {}
impl Default for OpenedSignal {
fn default() -> Self {
Self::new_closed()
}
}
impl SignalGet for OpenedSignal {
type Value = bool;
fn get(&self) -> bool {
self.0.get()
}
fn try_get(&self) -> Option<bool> {
self.0.try_get()
}
}
impl SignalWith for OpenedSignal {
type Value = bool;
fn with<U>(&self, f: impl FnOnce(&bool) -> U) -> U {
self.0.with(f)
}
fn try_with<O>(&self, f: impl FnOnce(&bool) -> O) -> Option<O> {
self.0.try_with(f)
}
}
impl FnOnce<()> for OpenedSignal {
type Output = bool;
#[inline(always)]
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
FnOnce::call_once(self.0, args)
}
}
impl FnMut<()> for OpenedSignal {
#[inline(always)]
extern "rust-call" fn call_mut(&mut self, args: ()) -> Self::Output {
FnOnce::call_once(self.0, args)
}
}
impl Fn<()> for OpenedSignal {
#[inline(always)]
extern "rust-call" fn call(&self, args: ()) -> Self::Output {
FnOnce::call_once(self.0, args)
}
} Edit: typo |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Cool! This looks like a good practice to me. No, you don't need to implement any of the traits you don't need, and this should work out of the box. However, the following logic is wrong: pub fn toggle(&self) {
// this should be .set(!self.0())
// more efficiently, self.o.update(|n| *n = !*n);
self.0.set(self.0());
}
pub fn open(&self) {
self.0.set(true);
}
pub fn close(&self) {
// should be self.0.set(false);
self.0.set(true);
} |
Beta Was this translation helpful? Give feedback.
Cool! This looks like a good practice to me. No, you don't need to implement any of the traits you don't need, and this should work out of the box.
However, the following logic is wrong: