use std::io::{
Result,
Seek,
SeekFrom,
};
pub struct PositionGuard<'a, S>
where
S: Seek + ?Sized,
{
stream: &'a mut S,
position: u64,
done: bool,
}
impl<'a, S> PositionGuard<'a, S>
where
S: Seek + ?Sized,
{
#[inline]
pub fn new(stream: &'a mut S) -> Result<Self> {
let position = stream.stream_position()?;
Ok(Self {
stream,
position,
done: false,
})
}
#[inline]
pub fn position(&self) -> u64 {
self.position
}
#[inline]
pub fn get_mut(&mut self) -> &mut S {
self.stream
}
pub fn restore(&mut self) -> Result<()> {
self.stream.seek(SeekFrom::Start(self.position)).map(|_| {
self.done = true;
})
}
#[inline]
pub fn dismiss(mut self) {
self.done = true;
}
}
impl<S> Drop for PositionGuard<'_, S>
where
S: Seek + ?Sized,
{
fn drop(&mut self) {
if !self.done {
drop(self.stream.seek(SeekFrom::Start(self.position)));
}
}
}