/// Common iterator types use wayland_server::{backend::ClientId, Resource, Weak}; use std::{fmt, sync::MutexGuard}; /// Iterator helper over a mutex of client objects pub struct LockedClientObjsIter<'a, T: 'static, G, F> { pub iterator: std::iter::FilterMap>, F>, pub guard: MutexGuard<'a, G>, } pub(crate) fn new_locked_obj_iter_from_vec( guard: MutexGuard<'_, Vec>>, client: ClientId, ) -> impl Iterator + '_ { new_locked_obj_iter(guard, client, |guard| guard.iter()) } pub(crate) fn new_locked_obj_iter< 'a, T: Resource + 'static, G, F: for<'b> FnOnce(&'b G) -> std::slice::Iter<'b, Weak>, >( guard: MutexGuard<'a, G>, client: ClientId, iterator_fn: F, ) -> impl Iterator + 'a { let iterator = unsafe { std::mem::transmute::>, std::slice::Iter<'static, Weak>>(iterator_fn( &*guard, )) }; let iterator = iterator.filter_map(move |p| { let client = &client; p.upgrade() .ok() .filter(|p| p.client().is_some_and(|c| c.id() == *client)) }); LockedClientObjsIter::<'a, T, G, _>::new_internal(iterator, guard) } impl<'a, T, G, F> LockedClientObjsIter<'a, T, G, F> { fn new_internal( iterator: std::iter::FilterMap>, F>, guard: MutexGuard<'a, G>, ) -> Self { LockedClientObjsIter { iterator, guard } } } impl Iterator for LockedClientObjsIter<'_, T, G, F> where F: FnMut(&'static Weak) -> Option, { type Item = T; fn next(&mut self) -> Option { self.iterator.next() } } impl fmt::Debug for LockedClientObjsIter<'_, T, G, F> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("LockedClientObjsIter") .field("inner", &self.guard) .finish() } }