use crate::events::UnknownEvent;
use crate::events::io::EventBatcher;
use crate::events::io::implementation::{InputEventBuffer, raw_input_events};
use crate::utils::usize_to_clap_size;
use clap_sys::events::clap_input_events;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::ops::{Index, Range};
#[repr(C)]
pub struct InputEvents<'a> {
inner: clap_input_events,
_lifetime: PhantomData<(&'a clap_input_events, *const ())>,
}
impl<'a> InputEvents<'a> {
#[inline]
pub const unsafe fn from_raw(raw: &'a clap_input_events) -> &'a Self {
&*(raw as *const _ as *const _)
}
#[inline]
pub const fn as_raw(&self) -> &clap_input_events {
&self.inner
}
#[inline]
pub const fn from_buffer<I: InputEventBuffer>(buffer: &'a I) -> Self {
Self {
inner: raw_input_events(buffer),
_lifetime: PhantomData,
}
}
#[inline]
pub const fn empty() -> InputEvents<'static> {
InputEvents::from_buffer::<[&UnknownEvent; 0]>(&[])
}
#[inline]
pub fn len(&self) -> u32 {
match self.inner.size {
None => 0,
Some(s) => unsafe { s(&self.inner) },
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn get(&self, index: u32) -> Option<&UnknownEvent> {
let event = unsafe { self.inner.get?(&self.inner, index) };
if event.is_null() {
return None;
};
unsafe { Some(UnknownEvent::from_raw(event)) }
}
#[inline]
pub fn iter(&self) -> InputEventsIter<'_> {
InputEventsIter {
list: self,
range: 0..self.len(),
}
}
#[inline]
pub fn iter_range(&self, range: Range<u32>) -> Option<InputEventsIter<'_>> {
let len = self.len();
if range.start > len || range.end > len {
None
} else {
Some(InputEventsIter { list: self, range })
}
}
#[inline]
pub fn batch(&self) -> EventBatcher<'_> {
EventBatcher::new(self)
}
}
impl<'a> IntoIterator for &'a InputEvents<'a> {
type Item = &'a UnknownEvent;
type IntoIter = InputEventsIter<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, I: InputEventBuffer> From<&'a I> for InputEvents<'a> {
#[inline]
fn from(implementation: &'a I) -> Self {
Self::from_buffer(implementation)
}
}
impl InputEventBuffer for InputEvents<'_> {
#[inline]
fn len(&self) -> u32 {
InputEvents::len(self)
}
#[inline]
fn get(&self, index: u32) -> Option<&UnknownEvent> {
InputEvents::get(self, index)
}
}
const INDEX_ERROR: &str = "Indexed InputEvents list out of bounds";
impl Index<usize> for InputEvents<'_> {
type Output = UnknownEvent;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
self.get(usize_to_clap_size(index)).expect(INDEX_ERROR)
}
}
impl Debug for InputEvents<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut list = f.debug_list();
for event in self {
if let Some(event) = event.as_core_event() {
list.entry(&event);
} else {
list.entry(&event);
}
}
list.finish()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct InputEventsIter<'a> {
list: &'a InputEvents<'a>,
range: Range<u32>,
}
impl<'a> InputEventsIter<'a> {
#[inline]
pub(crate) const fn new(list: &'a InputEvents<'a>, range: Range<u32>) -> Self {
Self { list, range }
}
}
impl Clone for InputEventsIter<'_> {
#[inline]
fn clone(&self) -> Self {
InputEventsIter {
list: self.list,
range: self.range.start..self.range.end,
}
}
}
impl<'a> Iterator for InputEventsIter<'a> {
type Item = &'a UnknownEvent;
fn next(&mut self) -> Option<Self::Item> {
self.range.next().and_then(|i| self.list.get(i))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
impl ExactSizeIterator for InputEventsIter<'_> {
#[inline]
fn len(&self) -> usize {
self.range.len()
}
}
impl DoubleEndedIterator for InputEventsIter<'_> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.range.next_back().and_then(|i| self.list.get(i))
}
}
#[cfg(test)]
mod test {
extern crate static_assertions as sa;
use super::*;
sa::assert_not_impl_any!(InputEvents<'static>: Send, Sync);
}