use std::{cmp, ptr};
use std::iter::FusedIterator;
use arrayvec::ArrayVec;
use crate::event::Event;
#[derive(Debug)]
pub struct Events {
events: ArrayVec<[Event; 256]>,
pos: usize,
}
impl Events {
pub fn new() -> Events {
Events { events: ArrayVec::new(), pos: 0 }
}
pub fn len(&self) -> usize {
let len = self.events.len();
if self.pos > len {
0
} else {
len - self.pos
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub(crate) fn clear(&mut self) {
unsafe { self.events.set_len(0); }
self.pos = 0;
}
pub(crate) fn capacity(&self) -> usize {
self.events.capacity()
}
pub(crate) fn push(&mut self, event: Event) {
self.events.push(event);
}
pub(crate) fn extend_events(&mut self, events: &[Event]) -> usize {
let count = cmp::min(self.capacity_left(), events.len());
if count == 0 {
return 0;
}
let len = self.len();
unsafe {
let dst = self.events.as_mut_ptr().add(len);
ptr::copy_nonoverlapping(events.as_ptr(), dst, count);
self.events.set_len(len + count);
}
count
}
pub(crate) fn capacity_left(&self) -> usize {
self.events.capacity() - self.events.len()
}
}
impl Default for Events {
fn default() -> Events {
Events::new()
}
}
impl<'a> Iterator for &'a mut Events {
type Item = Event;
fn next(&mut self) -> Option<Event> {
let ret = self.events.get(self.pos).cloned();
self.pos += 1;
ret
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<'a> ExactSizeIterator for &'a mut Events {
fn len(&self) -> usize {
(&**self).len()
}
}
impl<'a> FusedIterator for &'a mut Events { }
#[cfg(test)]
mod tests {
use std::iter::repeat;
use crate::event::{Events, Event, EventedId, Ready};
const EVENTS_CAP: usize = 256;
#[test]
fn push() {
let mut events = Events::default();
assert_eq!(events.len(), 0);
assert!(events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP);
assert_eq!((&mut events).len(), 0);
events.push(Event::new(EventedId(0), Ready::READABLE));
assert_eq!(events.len(), 1);
assert!(!events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP - 1);
assert_eq!((&mut events).len(), 1);
}
#[test]
fn clear() {
let mut events = Events::new();
events.push(Event::new(EventedId(0), Ready::ERROR));
events.clear();
assert_eq!(events.len(), 0);
assert!(events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP);
}
#[test]
fn extend_0() {
let mut events = Events::new();
assert_eq!(events.extend_events(&[]), 0);
assert_eq!(events.len(), 0);
assert!(events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP);
assert_eq!((&mut events).len(), 0);
}
#[test]
fn extend_many() {
let extra_events: [Event; 4] = [
Event::new(EventedId(0), Ready::READABLE),
Event::new(EventedId(1), Ready::READABLE),
Event::new(EventedId(2), Ready::READABLE),
Event::new(EventedId(3), Ready::READABLE),
];
let mut events = Events::new();
assert_eq!(events.extend_events(&extra_events), 4);
assert_eq!(events.len(), 4);
assert!(!events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP - 4);
assert_eq!((&mut events).len(), 4);
}
#[test]
fn extend_no_space() {
let iter = repeat(Event::new(EventedId(0), Ready::READABLE));
let extra_events: Vec<Event> = iter.take(EVENTS_CAP + 1).collect();
let mut events = Events::new();
assert_eq!(events.extend_events(&extra_events), EVENTS_CAP);
assert_eq!(events.len(), EVENTS_CAP);
assert!(!events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), 0);
assert_eq!((&mut events).len(), EVENTS_CAP);
assert_eq!(events.extend_events(&extra_events), 0);
}
#[test]
fn iter() {
let extra_events: [Event; 4] = [
Event::new(EventedId(0), Ready::WRITABLE),
Event::new(EventedId(1), Ready::WRITABLE),
Event::new(EventedId(2), Ready::WRITABLE),
Event::new(EventedId(3), Ready::WRITABLE),
];
let mut events = Events::new();
assert_eq!(events.extend_events(&extra_events), 4);
let mut current_id = 0;
for event in &mut events.take(2) {
assert_eq!(event.id(), EventedId(current_id));
assert_eq!(event.readiness(), Ready::WRITABLE);
current_id += 1;
}
assert_eq!(events.len(), 2);
assert!(!events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP - 4);
assert_eq!((&mut events).len(), 2);
for event in &mut events {
assert_eq!(event.id(), EventedId(current_id));
assert_eq!(event.readiness(), Ready::WRITABLE);
current_id += 1;
}
assert_eq!(current_id, 4);
assert_eq!(events.len(), 0);
assert!(events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP - 4);
assert_eq!((&mut events).len(), 0);
}
#[test]
fn fused_iter() {
let mut events = Events::new();
events.push(Event::new(EventedId(0), Ready::ERROR));
assert_eq!((&mut events).count(), 1);
assert_eq!(events.len(), 0);
assert!(events.is_empty());
assert_eq!(events.capacity(), EVENTS_CAP);
assert_eq!(events.capacity_left(), EVENTS_CAP - 1);
assert_eq!((&mut events).len(), 0);
for _ in 0..100 {
assert_eq!((&mut events).next(), None);
}
}
}