use std::iter::{Enumerate, Fuse, Skip, Take}; use super::{ConsumedIteratorGuard, IteratorGuard, LockingIterator}; use crate::{ lockable::{Lockable, RawLock, Sharable}, Keyable, }; impl LockingIterator { pub(crate) const fn new(key: Key, lockable: L) -> Self { Self { key, lockable } } fn with_iterator(self, f: impl FnOnce(L) -> M) -> LockingIterator { LockingIterator { key: self.key, lockable: f(self.lockable), } } } impl<'a, I: Iterator, L: 'a + Lockable + RawLock, Key: Keyable> LockingIterator { pub fn lock_next(&'a mut self) -> Option::Guard<'a>, Key>> { if let Some(lock) = self.lockable.next() { unsafe { lock.raw_write(); let guard = lock.guard(); Some(IteratorGuard { _key: &self.key, guard, }) } } else { None } } pub fn lock_last(self) -> Option::Guard<'a>, Key>> { self.lockable.last().map(|lock| unsafe { lock.raw_write(); let guard = lock.guard(); ConsumedIteratorGuard { key: self.key, guard, } }) } } impl<'a, I: Iterator, L: 'a + Sharable + RawLock, Key: Keyable> LockingIterator { pub fn read_next( &'a mut self, ) -> Option::ReadGuard<'a>, Key>> { if let Some(lock) = self.lockable.next() { unsafe { lock.raw_read(); let guard = lock.read_guard(); Some(IteratorGuard { _key: &self.key, guard, }) } } else { None } } pub fn read_last(self) -> Option::ReadGuard<'a>, Key>> { self.lockable.last().map(|lock| unsafe { lock.raw_read(); let guard = lock.read_guard(); ConsumedIteratorGuard { key: self.key, guard, } }) } } impl LockingIterator { pub fn size_hint(&self) -> (usize, Option) { self.lockable.size_hint() } pub fn enumerate(self) -> LockingIterator, Key> { self.with_iterator(Iterator::enumerate) } pub fn skip(self, n: usize) -> LockingIterator, Key> { self.with_iterator(|i| i.skip(n)) } pub fn take(self, n: usize) -> LockingIterator, Key> { self.with_iterator(|i| i.take(n)) } pub fn fuse(self) -> LockingIterator, Key> { self.with_iterator(Iterator::fuse) } }