use std::io::{
Result,
SeekFrom,
};
use crate::{
BufferedOutput,
Output,
Seekable,
SeekableOutput,
};
pub enum EnsuredBufferedOutput<O>
where
O: Output,
O::Item: Copy + Default,
{
AlreadyBuffered(O),
Buffered(BufferedOutput<O>),
}
impl<O> Output for EnsuredBufferedOutput<O>
where
O: Output,
O::Item: Copy + Default,
{
type Item = O::Item;
#[inline(always)]
fn is_buffered(&self) -> bool {
true
}
#[inline(always)]
unsafe fn write_unchecked(
&mut self,
input: &[Self::Item],
index: usize,
count: usize,
) -> Result<usize> {
match self {
Self::AlreadyBuffered(output) => {
unsafe { output.write_unchecked(input, index, count) }
}
Self::Buffered(output) => {
unsafe { output.write_unchecked(input, index, count) }
}
}
}
#[inline(always)]
fn write(&mut self, input: &[Self::Item]) -> Result<usize> {
match self {
Self::AlreadyBuffered(output) => output.write(input),
Self::Buffered(output) => output.write(input),
}
}
#[inline(always)]
unsafe fn write_fully_unchecked(
&mut self,
input: &[Self::Item],
index: usize,
count: usize,
) -> Result<()> {
match self {
Self::AlreadyBuffered(output) => {
unsafe { output.write_fully_unchecked(input, index, count) }
}
Self::Buffered(output) => {
unsafe { output.write_fully_unchecked(input, index, count) }
}
}
}
#[inline(always)]
fn write_fully(&mut self, input: &[Self::Item]) -> Result<()> {
match self {
Self::AlreadyBuffered(output) => output.write_fully(input),
Self::Buffered(output) => output.write_fully(input),
}
}
#[inline(always)]
fn flush(&mut self) -> Result<()> {
match self {
Self::AlreadyBuffered(output) => output.flush(),
Self::Buffered(output) => output.flush(),
}
}
}
impl<O> Seekable for EnsuredBufferedOutput<O>
where
O: SeekableOutput,
<O as Output>::Item: Copy + Default,
{
type Unit = <O as Output>::Item;
#[inline(always)]
fn seek_to(&mut self, position: SeekFrom) -> Result<u64> {
match self {
Self::AlreadyBuffered(output) => output.seek_to(position),
Self::Buffered(output) => output.seek_to(position),
}
}
}