use std::io::Result;
use std::io::SeekFrom;
use crate::BufferedInput;
use crate::Input;
use crate::Seekable;
use crate::SeekableInput;
#[must_use]
pub enum EnsuredBufferedInput<I>
where
I: Input,
I::Item: Clone + Default,
{
AlreadyBuffered(
I,
),
Buffered(
BufferedInput<I>,
),
}
impl<I> Input for EnsuredBufferedInput<I>
where
I: Input,
I::Item: Clone + Default,
{
type Item = I::Item;
#[inline(always)]
fn is_buffered(&self) -> bool {
true
}
#[inline]
unsafe fn read_unchecked(&mut self, output: &mut [Self::Item], index: usize, count: usize) -> Result<usize> {
match self {
Self::AlreadyBuffered(input) => {
unsafe { input.read_unchecked(output, index, count) }
}
Self::Buffered(input) => {
unsafe { input.read_unchecked(output, index, count) }
}
}
}
#[inline]
fn read(&mut self, output: &mut [Self::Item]) -> Result<usize> {
match self {
Self::AlreadyBuffered(input) => input.read(output),
Self::Buffered(input) => input.read(output),
}
}
#[inline]
unsafe fn read_fully_unchecked(&mut self, output: &mut [Self::Item], index: usize, count: usize) -> Result<usize> {
match self {
Self::AlreadyBuffered(input) => {
unsafe { input.read_fully_unchecked(output, index, count) }
}
Self::Buffered(input) => {
unsafe { input.read_fully_unchecked(output, index, count) }
}
}
}
#[inline]
fn read_fully(&mut self, output: &mut [Self::Item]) -> Result<usize> {
match self {
Self::AlreadyBuffered(input) => input.read_fully(output),
Self::Buffered(input) => input.read_fully(output),
}
}
}
impl<I> Seekable for EnsuredBufferedInput<I>
where
I: SeekableInput,
<I as Input>::Item: Clone + Default,
{
type Unit = <I as Input>::Item;
#[inline]
fn seek_to(&mut self, position: SeekFrom) -> Result<u64> {
match self {
Self::AlreadyBuffered(input) => input.seek_to(position),
Self::Buffered(input) => input.seek_to(position),
}
}
}