chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0)
1/// Common iterator types
2use wayland_server::{backend::ClientId, Resource, Weak};
3
4use std::{fmt, sync::MutexGuard};
5
6/// Iterator helper over a mutex of client objects
7pub struct LockedClientObjsIter<'a, T: 'static, G, F> {
8 pub iterator: std::iter::FilterMap<std::slice::Iter<'static, Weak<T>>, F>,
9 pub guard: MutexGuard<'a, G>,
10}
11
12pub(crate) fn new_locked_obj_iter_from_vec<T: Resource + 'static>(
13 guard: MutexGuard<'_, Vec<Weak<T>>>,
14 client: ClientId,
15) -> impl Iterator<Item = T> + '_ {
16 new_locked_obj_iter(guard, client, |guard| guard.iter())
17}
18
19pub(crate) fn new_locked_obj_iter<
20 'a,
21 T: Resource + 'static,
22 G,
23 F: for<'b> FnOnce(&'b G) -> std::slice::Iter<'b, Weak<T>>,
24>(
25 guard: MutexGuard<'a, G>,
26 client: ClientId,
27 iterator_fn: F,
28) -> impl Iterator<Item = T> + 'a {
29 let iterator = unsafe {
30 std::mem::transmute::<std::slice::Iter<'_, Weak<T>>, std::slice::Iter<'static, Weak<T>>>(iterator_fn(
31 &*guard,
32 ))
33 };
34
35 let iterator = iterator.filter_map(move |p| {
36 let client = &client;
37 p.upgrade()
38 .ok()
39 .filter(|p| p.client().is_some_and(|c| c.id() == *client))
40 });
41
42 LockedClientObjsIter::<'a, T, G, _>::new_internal(iterator, guard)
43}
44
45impl<'a, T, G, F> LockedClientObjsIter<'a, T, G, F> {
46 fn new_internal(
47 iterator: std::iter::FilterMap<std::slice::Iter<'static, Weak<T>>, F>,
48 guard: MutexGuard<'a, G>,
49 ) -> Self {
50 LockedClientObjsIter { iterator, guard }
51 }
52}
53
54impl<T, G, F> Iterator for LockedClientObjsIter<'_, T, G, F>
55where
56 F: FnMut(&'static Weak<T>) -> Option<T>,
57{
58 type Item = T;
59
60 fn next(&mut self) -> Option<Self::Item> {
61 self.iterator.next()
62 }
63}
64
65impl<T, G: fmt::Debug, F> fmt::Debug for LockedClientObjsIter<'_, T, G, F> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("LockedClientObjsIter")
68 .field("inner", &self.guard)
69 .finish()
70 }
71}