1#![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/main/examples/image/res/zng-logo-icon.png")]
2#![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/main/examples/image/res/zng-logo.png")]
3#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
9#![warn(unused_extern_crates)]
10#![warn(missing_docs)]
11
12use std::{any::Any, fmt, marker::PhantomData};
13
14use zng_unique_id::unique_id_64;
15
16pub use zng_unique_id::static_id;
17
18#[diagnostic::on_unimplemented(note = "`StateValue` is implemented for all `T: Any + Send + Sync`")]
25pub trait StateValue: Any + Send + Sync {}
26impl<T: Any + Send + Sync> StateValue for T {}
27
28unique_id_64! {
29 pub struct StateId<T: (StateValue)>;
45}
46zng_unique_id::impl_unique_id_bytemuck!(StateId<T: (StateValue)>);
47impl<T: StateValue> fmt::Debug for StateId<T> {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 #[cfg(debug_assertions)]
50 let t = pretty_type_name::pretty_type_name::<T>();
51 #[cfg(not(debug_assertions))]
52 let t = "$T";
53
54 if f.alternate() {
55 writeln!(f, "StateId<{t} {{")?;
56 writeln!(f, " id: {},", self.get())?;
57 writeln!(f, " sequential: {}", self.sequential())?;
58 writeln!(f, "}}")
59 } else {
60 write!(f, "StateId<{t}>({})", self.sequential())
61 }
62 }
63}
64
65pub struct StateMapRef<'a, U>(&'a state_map::StateMap, PhantomData<U>);
69impl<U> Clone for StateMapRef<'_, U> {
70 fn clone(&self) -> Self {
71 *self
72 }
73}
74impl<U> Copy for StateMapRef<'_, U> {}
75impl<U> fmt::Debug for StateMapRef<'_, U> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(
78 f,
79 "StateMapRef<{}>({} entries);",
80 pretty_type_name::pretty_type_name::<U>(),
81 self.0.len()
82 )
83 }
84}
85impl<U> StateMapRef<'static, U> {
86 pub fn empty() -> Self {
88 static EMPTY: state_map::StateMap = state_map::StateMap::new();
89 Self(&EMPTY, PhantomData)
90 }
91}
92impl<'a, U> StateMapRef<'a, U> {
93 pub fn contains<T: StateValue>(self, id: impl Into<StateId<T>>) -> bool {
95 self.0.contains(id.into())
96 }
97
98 pub fn get<T: StateValue>(self, id: impl Into<StateId<T>>) -> Option<&'a T> {
100 self.0.get(id.into())
101 }
102
103 pub fn copy<T: StateValue + Copy>(self, id: impl Into<StateId<T>>) -> Option<T> {
105 self.get(id.into()).copied()
106 }
107
108 pub fn get_clone<T: StateValue + Clone>(self, id: impl Into<StateId<T>>) -> Option<T> {
110 self.get(id.into()).cloned()
111 }
112
113 pub fn req<T: StateValue>(self, id: impl Into<StateId<T>>) -> &'a T {
115 self.0.req(id.into())
116 }
117
118 pub fn flagged(self, id: impl Into<StateId<()>>) -> bool {
120 self.0.flagged(id.into())
121 }
122
123 pub fn is_empty(self) -> bool {
125 self.0.is_empty()
126 }
127
128 pub fn ptr_eq(self, other: Self) -> bool {
130 std::ptr::eq(self.0, other.0)
131 }
132}
133
134pub struct StateMapMut<'a, U>(&'a mut state_map::StateMap, PhantomData<U>);
138impl<U> fmt::Debug for StateMapMut<'_, U> {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(f, "StateMapMut<{}>({} entries);", std::any::type_name::<U>(), self.0.len())
141 }
142}
143impl<'a, U> StateMapMut<'a, U> {
144 pub fn contains<T: StateValue>(&self, id: impl Into<StateId<T>>) -> bool {
146 self.0.contains(id.into())
147 }
148
149 pub fn get<T: StateValue>(&self, id: impl Into<StateId<T>>) -> Option<&T> {
151 self.0.get(id.into())
152 }
153
154 pub fn into_get<T: StateValue>(self, id: impl Into<StateId<T>>) -> Option<&'a T> {
156 self.0.get(id.into())
157 }
158
159 pub fn copy<T: StateValue + Copy>(&self, id: impl Into<StateId<T>>) -> Option<T> {
161 self.get(id.into()).copied()
162 }
163
164 pub fn get_clone<T: StateValue + Clone>(&self, id: impl Into<StateId<T>>) -> Option<T> {
166 self.get(id).cloned()
167 }
168
169 pub fn req<T: StateValue>(&self, id: impl Into<StateId<T>>) -> &T {
171 self.0.req(id.into())
172 }
173
174 pub fn into_req<T: StateValue>(self, id: impl Into<StateId<T>>) -> &'a T {
176 self.0.req(id.into())
177 }
178
179 pub fn flagged(&self, id: impl Into<StateId<()>>) -> bool {
181 self.0.flagged(id.into())
182 }
183
184 pub fn is_empty(&self) -> bool {
186 self.0.is_empty()
187 }
188
189 pub fn set<T: StateValue>(&mut self, id: impl Into<StateId<T>>, value: impl Into<T>) -> Option<T> {
191 self.0.set(id.into(), value.into())
192 }
193
194 pub fn get_mut<T: StateValue>(&mut self, id: impl Into<StateId<T>>) -> Option<&mut T> {
196 self.0.get_mut(id.into())
197 }
198
199 pub fn into_get_mut<T: StateValue>(self, id: impl Into<StateId<T>>) -> Option<&'a mut T> {
201 self.0.get_mut(id.into())
202 }
203
204 pub fn req_mut<T: StateValue>(&mut self, id: impl Into<StateId<T>>) -> &mut T {
206 self.0.req_mut(id.into())
207 }
208
209 pub fn into_req_mut<T: StateValue>(self, id: impl Into<StateId<T>>) -> &'a mut T {
211 self.0.req_mut(id.into())
212 }
213
214 pub fn entry<T: StateValue>(&mut self, id: impl Into<StateId<T>>) -> state_map::StateMapEntry<T> {
216 self.0.entry(id.into())
217 }
218
219 pub fn into_entry<T: StateValue>(self, id: impl Into<StateId<T>>) -> state_map::StateMapEntry<'a, T> {
221 self.0.entry(id.into())
222 }
223
224 pub fn flag(&mut self, id: impl Into<StateId<()>>) -> bool {
228 self.0.flag(id.into())
229 }
230
231 pub fn reborrow(&mut self) -> StateMapMut<U> {
233 StateMapMut(self.0, PhantomData)
234 }
235
236 pub fn as_ref(&self) -> StateMapRef<U> {
238 StateMapRef(self.0, PhantomData)
239 }
240}
241
242pub struct OwnedStateMap<U>(state_map::StateMap, PhantomData<U>);
250impl<U> fmt::Debug for OwnedStateMap<U> {
251 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252 write!(
253 f,
254 "OwnedStateMap<{}>({} entries);",
255 pretty_type_name::pretty_type_name::<U>(),
256 self.0.len()
257 )
258 }
259}
260impl<U> Default for OwnedStateMap<U> {
261 fn default() -> Self {
262 Self::new()
263 }
264}
265impl<U> OwnedStateMap<U> {
266 pub const fn new() -> Self {
268 OwnedStateMap(state_map::StateMap::new(), PhantomData)
269 }
270
271 pub fn remove<T: StateValue>(&mut self, id: impl Into<StateId<T>>) -> Option<T> {
273 self.0.remove(id.into())
274 }
275
276 pub fn clear(&mut self) {
278 self.0.clear()
279 }
280
281 pub fn borrow(&self) -> StateMapRef<U> {
283 StateMapRef(&self.0, PhantomData)
284 }
285
286 pub fn borrow_mut(&mut self) -> StateMapMut<U> {
288 StateMapMut(&mut self.0, PhantomData)
289 }
290}
291
292pub mod state_map {
294 use std::any::Any;
295
296 use zng_unique_id::*;
297
298 use super::*;
299
300 type AnyMap = IdMap<u64, Box<dyn Any + Send + Sync>>;
301
302 pub(super) struct StateMap {
303 map: AnyMap,
304 }
305 impl StateMap {
306 pub(super) const fn new() -> Self {
307 StateMap { map: AnyMap::new() }
308 }
309
310 pub(super) fn len(&self) -> usize {
311 self.map.len()
312 }
313
314 pub(super) fn remove<T: StateValue>(&mut self, id: StateId<T>) -> Option<T> {
315 self.map.remove(&id.get()).map(|a| *a.downcast().unwrap())
316 }
317
318 pub(super) fn clear(&mut self) {
319 self.map.clear()
320 }
321
322 pub fn set<T: StateValue>(&mut self, id: StateId<T>, value: T) -> Option<T> {
323 self.map.insert(id.get(), Box::new(value)).map(|any| *any.downcast().unwrap())
324 }
325
326 pub fn contains<T: StateValue>(&self, id: StateId<T>) -> bool {
327 self.map.contains_key(&id.get())
328 }
329
330 pub fn get<T: StateValue>(&self, id: StateId<T>) -> Option<&T> {
331 self.map.get(&id.get()).map(|any| any.downcast_ref().unwrap())
332 }
333
334 pub fn get_mut<T: StateValue>(&mut self, id: StateId<T>) -> Option<&mut T> {
335 self.map.get_mut(&id.get()).map(|any| any.downcast_mut().unwrap())
336 }
337
338 pub fn req<T: StateValue>(&self, id: StateId<T>) -> &T {
339 self.get(id).unwrap_or_else(move || panic!("expected `{id:?}` in state map"))
340 }
341
342 pub fn req_mut<T: StateValue>(&mut self, id: StateId<T>) -> &mut T {
343 self.get_mut(id).unwrap_or_else(move || panic!("expected `{id:?}` in state map"))
344 }
345
346 pub fn entry<T: StateValue>(&mut self, id: StateId<T>) -> StateMapEntry<T> {
347 match self.map.entry(id.get()) {
348 IdEntry::Occupied(e) => StateMapEntry::Occupied(OccupiedStateMapEntry {
349 _type: PhantomData,
350 entry: e,
351 }),
352 IdEntry::Vacant(e) => StateMapEntry::Vacant(VacantStateMapEntry {
353 _type: PhantomData,
354 entry: e,
355 }),
356 }
357 }
358
359 pub fn flag(&mut self, id: StateId<()>) -> bool {
360 self.set(id, ()).is_some()
361 }
362
363 pub fn flagged(&self, id: StateId<()>) -> bool {
364 self.map.contains_key(&id.get())
365 }
366
367 pub fn is_empty(&self) -> bool {
368 self.map.is_empty()
369 }
370 }
371
372 pub struct OccupiedStateMapEntry<'a, T: StateValue> {
376 _type: PhantomData<T>,
377 entry: IdOccupiedEntry<'a, u64, Box<dyn Any + Send + Sync>>,
378 }
379 impl<'a, T: StateValue> OccupiedStateMapEntry<'a, T> {
380 pub fn get(&self) -> &T {
382 self.entry.get().downcast_ref().unwrap()
383 }
384
385 pub fn get_mut(&mut self) -> &mut T {
391 self.entry.get_mut().downcast_mut().unwrap()
392 }
393
394 pub fn into_mut(self) -> &'a mut T {
396 self.entry.into_mut().downcast_mut().unwrap()
397 }
398
399 pub fn insert(&mut self, value: T) -> T {
401 *self.entry.insert(Box::new(value)).downcast().unwrap()
402 }
403
404 pub fn remove(self) -> T {
406 *self.entry.remove().downcast().unwrap()
407 }
408 }
409 impl<T: StateValue + fmt::Debug> fmt::Debug for OccupiedStateMapEntry<'_, T> {
410 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
411 let id = StateId::<T>::from_raw(*self.entry.key());
412 f.debug_struct("OccupiedStateMapEntry")
413 .field("key", &id)
414 .field("value", self.get())
415 .finish()
416 }
417 }
418
419 pub struct VacantStateMapEntry<'a, T: StateValue> {
423 _type: PhantomData<T>,
424 entry: IdVacantEntry<'a, u64, Box<dyn Any + Send + Sync>>,
425 }
426 impl<'a, T: StateValue> VacantStateMapEntry<'a, T> {
427 pub fn insert(self, value: impl Into<T>) -> &'a mut T {
429 self.entry.insert(Box::new(value.into())).downcast_mut().unwrap()
430 }
431 }
432 impl<T: StateValue + fmt::Debug> fmt::Debug for VacantStateMapEntry<'_, T> {
433 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434 let id = StateId::<T>::from_raw(*self.entry.key());
435 f.debug_struct("VacantStateMapEntry").field("key", &id).finish_non_exhaustive()
436 }
437 }
438
439 pub enum StateMapEntry<'a, T: StateValue> {
445 Occupied(OccupiedStateMapEntry<'a, T>),
447 Vacant(VacantStateMapEntry<'a, T>),
449 }
450 impl<'a, T: StateValue> StateMapEntry<'a, T> {
451 pub fn or_insert(self, default: impl Into<T>) -> &'a mut T {
454 match self {
455 StateMapEntry::Occupied(e) => e.into_mut(),
456 StateMapEntry::Vacant(e) => e.insert(default),
457 }
458 }
459
460 pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> &'a mut T {
463 match self {
464 StateMapEntry::Occupied(e) => e.into_mut(),
465 StateMapEntry::Vacant(e) => e.insert(default()),
466 }
467 }
468
469 pub fn and_modify<F: FnOnce(&mut T)>(mut self, f: F) -> Self {
471 if let StateMapEntry::Occupied(e) = &mut self {
472 f(e.get_mut())
473 }
474 self
475 }
476 }
477 impl<'a, T: StateValue> StateMapEntry<'a, T>
478 where
479 T: Default,
480 {
481 pub fn or_default(self) -> &'a mut T {
484 self.or_insert_with(Default::default)
485 }
486 }
487 impl<T: StateValue + fmt::Debug> fmt::Debug for StateMapEntry<'_, T> {
488 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489 match self {
490 Self::Occupied(arg0) => f.debug_tuple("Occupied").field(arg0).finish(),
491 Self::Vacant(arg0) => f.debug_tuple("Vacant").field(arg0).finish(),
492 }
493 }
494 }
495}