yew_hooks/hooks/use_set.rs
1use std::cell::{Ref, RefCell};
2use std::collections::HashSet;
3use std::hash::Hash;
4use std::rc::Rc;
5
6use yew::prelude::*;
7
8use super::use_update;
9
10/// State handle for the [`use_set`] hook.
11pub struct UseSetHandle<T> {
12 inner: Rc<RefCell<HashSet<T>>>,
13 update: Rc<dyn Fn()>,
14}
15
16impl<T> UseSetHandle<T> {
17 /// Get immutable ref to the set.
18 ///
19 /// # Panics
20 ///
21 /// Panics if the value is currently mutably borrowed
22 pub fn current(&self) -> Ref<HashSet<T>> {
23 self.inner.borrow()
24 }
25
26 /// Set the hash set.
27 pub fn set(&self, set: HashSet<T>) {
28 *self.inner.borrow_mut() = set;
29 (self.update)();
30 }
31
32 /// Adds a value to the set.
33 pub fn insert(&self, value: T) -> bool
34 where
35 T: Eq + Hash,
36 {
37 let present = self.inner.borrow_mut().insert(value);
38 (self.update)();
39 present
40 }
41
42 /// Adds a value to the set, replacing the existing value,
43 /// if any, that is equal to the given one. Returns the replaced value.
44 pub fn replace(&self, value: T) -> Option<T>
45 where
46 T: Eq + Hash,
47 {
48 let v = self.inner.borrow_mut().replace(value);
49 (self.update)();
50 v
51 }
52
53 /// Removes a value from the set. Returns whether the value was present in the set.
54 pub fn remove(&self, value: &T) -> bool
55 where
56 T: Eq + Hash,
57 {
58 let present = self.inner.borrow_mut().remove(value);
59 (self.update)();
60 present
61 }
62
63 /// Retains only the elements specified by the predicate.
64 pub fn retain<F>(&self, f: F)
65 where
66 T: Eq + Hash,
67 F: FnMut(&T) -> bool,
68 {
69 self.inner.borrow_mut().retain(f);
70 (self.update)();
71 }
72
73 /// Clears the set, removing all values.
74 pub fn clear(&self) {
75 self.inner.borrow_mut().clear();
76 (self.update)();
77 }
78}
79
80impl<T> Clone for UseSetHandle<T> {
81 fn clone(&self) -> Self {
82 Self {
83 inner: self.inner.clone(),
84 update: self.update.clone(),
85 }
86 }
87}
88
89impl<T> PartialEq for UseSetHandle<T>
90where
91 T: Eq + Hash,
92{
93 fn eq(&self, other: &Self) -> bool {
94 *self.inner == *other.inner
95 }
96}
97
98/// A hook that tracks a hash set and provides methods to modify it.
99///
100/// # Example
101///
102/// ```rust
103/// # use std::collections::HashSet;
104/// # use yew::prelude::*;
105/// #
106/// use yew_hooks::prelude::*;
107///
108/// #[function_component(UseSet)]
109/// fn set() -> Html {
110/// let set = use_set(HashSet::from(["Mercury", "Venus", "Earth", "Mars"]));
111///
112/// let onset = {
113/// let set = set.clone();
114/// Callback::from(move |_| set.set(HashSet::from(["Moon", "Earth"])))
115/// };
116/// let oninsert = {
117/// let set = set.clone();
118/// Callback::from(move |_| {
119/// let _ = set.insert("Jupiter");
120/// })
121/// };
122/// let onreplace = {
123/// let set = set.clone();
124/// Callback::from(move |_| {
125/// let _ = set.replace("Earth");
126/// })
127/// };
128/// let onremove = {
129/// let set = set.clone();
130/// Callback::from(move |_| {
131/// let _ = set.remove(&"Moon");
132/// })
133/// };
134/// let onretain = {
135/// let set = set.clone();
136/// Callback::from(move |_| set.retain(|v| v.contains('a')))
137/// };
138/// let onclear = {
139/// let set = set.clone();
140/// Callback::from(move |_| set.clear())
141/// };
142///
143/// html! {
144/// <div>
145/// <button onclick={onset}>{ "Set" }</button>
146/// <button onclick={oninsert}>{ "Insert" }</button>
147/// <button onclick={onreplace}>{ "Replace" }</button>
148/// <button onclick={onremove}>{ "Remove" }</button>
149/// <button onclick={onretain}>{ "Retain" }</button>
150/// <button onclick={onclear}>{ "Clear all" }</button>
151/// <p>
152/// <b>{ "Current value: " }</b>
153/// </p>
154/// {
155/// for set.current().iter().map(|v| {
156/// html! {
157/// <p><b>{ v }</b></p>
158/// }
159/// })
160/// }
161/// </div>
162/// }
163/// }
164/// ```
165#[hook]
166pub fn use_set<T>(initial_value: HashSet<T>) -> UseSetHandle<T>
167where
168 T: 'static,
169{
170 let inner = use_mut_ref(|| initial_value);
171 let update = use_update();
172
173 UseSetHandle { inner, update }
174}