1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::{
    collections::VecDeque,
    iter::{
        Iterator, IntoIterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator,
    },
    fmt::{self, Formatter},
};
use parking_lot::{
    Mutex,
    MutexGuard,
};

/// Recieves events from event feeds and queues them until they are processed.
pub struct Reader<Evt>
where Evt: Send {
    queue: Mutex<VecDeque<Evt>>,
}
impl<Evt> Reader<Evt>
where Evt: Send {
    /// Creates an iterator which reads and removes the events from the queue.
    ///
    /// The queue's mutex remains locked for the entire lifetime of the returned iterator, which means that all calls to the feed's `send_with`, `send` and others will block. If you do not want that behavior, drop the iterator after a number of iterations and create a new one, which should cause a fair mutex unlock if it ran for long enough, allowing the feed to send new events.
    #[inline(always)]
    pub fn read(&self) -> ReaderIter<'_, Evt> {
        ReaderIter {
            queue: self.queue.lock()
        }
    }
    /// Reads the entire queue by using the specified closure to process the events. Useful for simple event handling, i.e. if the closure doesn't return anything depending on how it processes the events. If it does, using `read` directly is necesarry.
    ///
    /// See `read` for the mutex-related implications of using this.
    #[inline(always)]
    pub fn read_with<F>(&self, f: F)
    where F: FnMut(Evt) {
        self.read().for_each(f);
    }
    /// Creates a reader.
    ///
    /// This method is not meant to be exposed to library users. The correct method which you should use for creating readers is `Feed`'s `add_reader`.
    #[inline(always)]
    pub(crate) fn new() -> Self {
        Self {
            queue: Mutex::new(VecDeque::new()),
        }
    }
    /// Recieves the specified event by putting it into the queue.
    ///
    /// This method is not meant to be exposed to library users. The only place where it should be called is `Feed`'s `send_with` and its variations.
    #[inline]
    pub(crate) fn recieve(&self, event: Evt) {
        let mut queue = self.queue.lock();
        queue.push_back(event);
    }
}
impl<Evt> fmt::Debug for Reader<Evt>
where Evt: fmt::Debug + Send {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.debug_struct("Reader")
            .field("queue", &*self.queue.lock())
        .finish()
    }
}
impl<'r, Evt> IntoIterator for &'r Reader<Evt>
where Evt: Send {
    type IntoIter = ReaderIter<'r, Evt>;
    type Item = Evt;
    /// Creates an iterator which reads and removes events from the queue.
    ///
    /// Equivalent to `self.read()`, intended to be used in `for` loops.
    #[inline(always)]
    fn into_iter(self) -> ReaderIter<'r, Evt> {
        self.read()
    }
}

/// An iterator used for processing events in an event reader's queue.
///
/// Use the `read` method to acquire this.
pub struct ReaderIter<'r, Evt>
where Evt: Send {
    queue: MutexGuard<'r, VecDeque<Evt>>,
}
impl<'r, Evt> Iterator for ReaderIter<'r, Evt>
where Evt: Send {
    type Item = Evt;
    
    #[inline(always)]
    fn next(&mut self) -> Option<Evt> {
        self.queue.pop_front()
    }
    #[inline(always)]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (
            self.len(),
            Some(self.len())
        )
    }
    #[inline(always)]
    fn count(self) -> usize {
        self.len()
    }
}
impl<'r, Evt> DoubleEndedIterator for ReaderIter<'r, Evt>
where Evt: Send {
    #[inline(always)]
    fn next_back(&mut self) -> Option<Evt> {
        self.queue.pop_back()
    }
}
impl<'r, Evt> ExactSizeIterator for ReaderIter<'r, Evt>
where Evt: Send {
    #[inline(always)]
    fn len(&self) -> usize {
        self.queue.len()
    }
}
impl<Evt> FusedIterator for ReaderIter<'_, Evt>
where Evt: Send {}