yew/functional/hooks/
use_state.rs1use std::fmt;
2use std::ops::Deref;
3use std::rc::Rc;
4
5use implicit_clone::ImplicitClone;
6
7use super::{use_reducer, use_reducer_eq, Reducible, UseReducerDispatcher, UseReducerHandle};
8use crate::functional::hook;
9use crate::html::IntoPropValue;
10use crate::Callback;
11
12struct UseStateReducer<T> {
13 value: T,
14}
15
16impl<T> Reducible for UseStateReducer<T> {
17 type Action = T;
18
19 fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
20 Rc::new(Self { value: action })
21 }
22}
23
24impl<T> PartialEq for UseStateReducer<T>
25where
26 T: PartialEq,
27{
28 fn eq(&self, rhs: &Self) -> bool {
29 self.value == rhs.value
30 }
31}
32
33#[hook]
80pub fn use_state<T, F>(init_fn: F) -> UseStateHandle<T>
81where
82 T: 'static,
83 F: FnOnce() -> T,
84{
85 let handle = use_reducer(move || UseStateReducer { value: init_fn() });
86
87 UseStateHandle { inner: handle }
88}
89
90#[hook]
94pub fn use_state_eq<T, F>(init_fn: F) -> UseStateHandle<T>
95where
96 T: PartialEq + 'static,
97 F: FnOnce() -> T,
98{
99 let handle = use_reducer_eq(move || UseStateReducer { value: init_fn() });
100
101 UseStateHandle { inner: handle }
102}
103
104pub struct UseStateHandle<T> {
106 inner: UseReducerHandle<UseStateReducer<T>>,
107}
108
109impl<T: fmt::Debug> fmt::Debug for UseStateHandle<T> {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.debug_struct("UseStateHandle")
112 .field("value", &format!("{:?}", self.inner.value))
113 .finish()
114 }
115}
116
117impl<T> UseStateHandle<T> {
118 pub fn set(&self, value: T) {
120 self.inner.dispatch(value)
121 }
122
123 pub fn setter(&self) -> UseStateSetter<T> {
125 UseStateSetter {
126 inner: self.inner.dispatcher(),
127 }
128 }
129}
130
131impl<T> Deref for UseStateHandle<T> {
132 type Target = T;
133
134 fn deref(&self) -> &Self::Target {
135 &(*self.inner).value
136 }
137}
138
139impl<T> Clone for UseStateHandle<T> {
140 fn clone(&self) -> Self {
141 Self {
142 inner: self.inner.clone(),
143 }
144 }
145}
146
147impl<T> PartialEq for UseStateHandle<T>
148where
149 T: PartialEq,
150{
151 fn eq(&self, rhs: &Self) -> bool {
152 *self.inner == *rhs.inner
153 }
154}
155
156impl<T> ImplicitClone for UseStateHandle<T> {}
157
158pub struct UseStateSetter<T> {
160 inner: UseReducerDispatcher<UseStateReducer<T>>,
161}
162
163impl<T> Clone for UseStateSetter<T> {
164 fn clone(&self) -> Self {
165 Self {
166 inner: self.inner.clone(),
167 }
168 }
169}
170
171impl<T> fmt::Debug for UseStateSetter<T>
172where
173 T: fmt::Debug,
174{
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 f.debug_struct("UseStateSetter").finish()
177 }
178}
179
180impl<T> From<UseStateSetter<T>> for Callback<T> {
181 fn from(value: UseStateSetter<T>) -> Self {
182 Self::from(value.inner)
183 }
184}
185
186impl<T> IntoPropValue<Callback<T>> for UseStateSetter<T> {
187 fn into_prop_value(self) -> Callback<T> {
188 self.inner.into_prop_value()
189 }
190}
191
192impl<T> PartialEq for UseStateSetter<T> {
193 fn eq(&self, rhs: &Self) -> bool {
194 self.inner == rhs.inner
195 }
196}
197
198impl<T> ImplicitClone for UseStateSetter<T> {}
199
200impl<T> UseStateSetter<T> {
201 pub fn set(&self, value: T) {
203 self.inner.dispatch(value)
204 }
205
206 pub fn to_callback(&self) -> Callback<T> {
209 self.inner.to_callback()
210 }
211}