1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! use_counter hook for numeric state management
//!
//! Provides convenient methods for incrementing, decrementing, and
//! resetting numeric values.
//!
//! # Example
//!
//! ```rust,ignore
//! use rnk::prelude::*;
//!
//! fn app() -> Element {
//! let counter = use_counter(0);
//!
//! use_input(move |_, key| {
//! if key.up_arrow {
//! counter.increment();
//! } else if key.down_arrow {
//! counter.decrement();
//! } else if key.return_key {
//! counter.reset();
//! }
//! });
//!
//! Text::new(format!("Count: {}", counter.get())).into_element()
//! }
//! ```
use crate::hooks::use_signal::{Signal, use_signal};
use std::ops::{AddAssign, SubAssign};
/// Handle for counter operations
#[derive(Clone)]
pub struct CounterHandle<T> {
signal: Signal<T>,
initial: T,
}
impl<T> CounterHandle<T>
where
T: Clone + Send + Sync + 'static,
{
/// Get the current value
pub fn get(&self) -> T {
self.signal.get()
}
/// Set to a specific value
pub fn set(&self, value: T) {
self.signal.set(value);
}
/// Reset to initial value
pub fn reset(&self) {
self.signal.set(self.initial.clone());
}
}
impl<T> CounterHandle<T>
where
T: Clone + Send + Sync + AddAssign + From<u8> + 'static,
{
/// Increment by 1
pub fn increment(&self) {
self.signal.update(|v| *v += T::from(1));
}
/// Increment by a specific amount
pub fn increment_by(&self, amount: T) {
self.signal.update(|v| *v += amount);
}
}
impl<T> CounterHandle<T>
where
T: Clone + Send + Sync + SubAssign + From<u8> + 'static,
{
/// Decrement by 1
pub fn decrement(&self) {
self.signal.update(|v| *v -= T::from(1));
}
/// Decrement by a specific amount
pub fn decrement_by(&self, amount: T) {
self.signal.update(|v| *v -= amount);
}
}
/// Create a counter with the given initial value
pub fn use_counter<T>(initial: T) -> CounterHandle<T>
where
T: Clone + Send + Sync + 'static,
{
let signal = use_signal(|| initial.clone());
CounterHandle { signal, initial }
}
/// Create a counter starting at 0
pub fn use_counter_zero() -> CounterHandle<i32> {
use_counter(0i32)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_use_counter_compiles() {
fn _test() {
let counter = use_counter(0i32);
counter.increment();
counter.decrement();
counter.reset();
let _ = counter.get();
}
}
#[test]
fn test_use_counter_zero_compiles() {
fn _test() {
let counter = use_counter_zero();
counter.increment();
}
}
}