use crate::wad::{RawLump, Tag};
use crate::wad::ffi::{doom, halflife, quake};
use core::iter::FusedIterator;
use core::slice;
#[derive(Clone, Debug, Default)]
#[must_use]
pub(super) struct RawLumpSliceIter<'a>(Inner<'a>);
impl<'a> From<slice::Iter<'a, doom::filelump_t>> for RawLumpSliceIter<'a> {
#[inline(always)]
fn from(value: slice::Iter<'a, doom::filelump_t>) -> Self {
let inner = Inner::Wad(value);
Self(inner)
}
}
impl<'a> From<slice::Iter<'a, halflife::lumpinfo_t>> for RawLumpSliceIter<'a> {
#[inline(always)]
fn from(value: slice::Iter<'a, halflife::lumpinfo_t>) -> Self {
let inner = Inner::Wad3(value);
Self(inner)
}
}
impl<'a> From<slice::Iter<'a, quake::lumpinfo_t>> for RawLumpSliceIter<'a> {
#[inline(always)]
fn from(value: slice::Iter<'a, quake::lumpinfo_t>) -> Self {
let inner = Inner::Wad2(value);
Self(inner)
}
}
impl DoubleEndedIterator for RawLumpSliceIter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
match self.0 {
Inner::Wad(ref mut iter) => {
iter.next_back().map(Into::into)
}
Inner::Wad2(ref mut iter) => {
iter.next_back().map(Into::into)
}
Inner::Wad3(ref mut iter) => {
iter.next_back().map(Into::into)
}
}
}
}
impl ExactSizeIterator for RawLumpSliceIter<'_> {}
impl FusedIterator for RawLumpSliceIter<'_> {}
impl<'a> Iterator for RawLumpSliceIter<'a> {
type Item = RawLump<'a>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.0 {
Inner::Wad(ref mut iter) => {
iter.next().map(Into::into)
}
Inner::Wad2(ref mut iter) => {
iter.next().map(Into::into)
}
Inner::Wad3(ref mut iter) => {
iter.next().map(Into::into)
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self.0 {
Inner::Wad(ref iter) => {
iter.size_hint()
}
Inner::Wad2(ref iter) => {
iter.size_hint()
}
Inner::Wad3(ref iter) => {
iter.size_hint()
}
}
}
}
#[repr(u8)]
#[derive(Clone, Debug)]
enum Inner<'a> {
Wad(slice::Iter<'a, doom::filelump_t>) = Tag::Wad as u8,
Wad2(slice::Iter<'a, quake::lumpinfo_t>) = Tag::Wad2 as u8,
Wad3(slice::Iter<'a, halflife::lumpinfo_t>) = Tag::Wad3 as u8,
}
impl Default for Inner<'_> {
#[inline]
fn default() -> Self {
Self::Wad(Default::default())
}
}