use std::io;
use std::io::{Seek, SeekFrom};
pub trait Sink {
fn write_all(&mut self, buf: &[u8]) -> io::Result<()>;
}
impl<W: io::Write + ?Sized> Sink for W {
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
io::Write::write_all(self, buf)
}
}
pub trait RewindableSink: Sink {
fn rewind_to(&mut self, len: u64) -> io::Result<()>;
}
impl RewindableSink for std::fs::File {
fn rewind_to(&mut self, len: u64) -> io::Result<()> {
self.set_len(len)?;
self.seek(SeekFrom::Start(len))?;
Ok(())
}
}
impl RewindableSink for Vec<u8> {
fn rewind_to(&mut self, len: u64) -> io::Result<()> {
self.truncate(len as usize);
Ok(())
}
}
impl RewindableSink for std::io::Cursor<Vec<u8>> {
fn rewind_to(&mut self, len: u64) -> io::Result<()> {
self.get_mut().truncate(len as usize);
self.set_position(len);
Ok(())
}
}
impl<S: RewindableSink + io::Write + ?Sized> RewindableSink for &mut S {
fn rewind_to(&mut self, len: u64) -> io::Result<()> {
(**self).rewind_to(len)
}
}
pub(crate) struct WriteCtx<'a, S: Sink> {
pub sink: &'a mut S,
pub pos: &'a mut u64,
pub scratch: &'a mut Vec<u8>,
pub padding_written: &'a mut u64,
}