use std::io::Result;
use std::io::SeekFrom;
use crate::BufferedOutput;
use crate::Output;
use crate::Seekable;
use crate::SeekableOutput;
#[must_use]
pub enum EnsuredBufferedOutput<O>
where
O: Output,
O::Item: Clone + Default,
{
AlreadyBuffered(
O,
),
Buffered(
BufferedOutput<O>,
),
}
impl<O> Output for EnsuredBufferedOutput<O>
where
O: Output,
O::Item: Clone + Default,
{
type Item = O::Item;
#[inline(always)]
fn is_buffered(&self) -> bool {
true
}
#[inline]
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]
fn write(&mut self, input: &[Self::Item]) -> Result<usize> {
match self {
Self::AlreadyBuffered(output) => output.write(input),
Self::Buffered(output) => output.write(input),
}
}
#[inline]
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]
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]
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: Clone + Default,
{
type Unit = <O as Output>::Item;
#[inline]
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),
}
}
}