use std::io::Result;
use std::io::SeekFrom;
use crate::Seekable;
#[must_use = "dropping an unused guard restores the captured position immediately"]
pub struct PositionGuard<'a, S>
where
S: Seekable + ?Sized,
{
stream: &'a mut S,
position: u64,
done: bool,
}
impl<'a, S> PositionGuard<'a, S>
where
S: Seekable + ?Sized,
{
#[inline]
pub fn new(stream: &'a mut S) -> Result<Self> {
let position = stream.seek_to(SeekFrom::Current(0))?;
Ok(Self {
stream,
position,
done: false,
})
}
#[inline(always)]
#[must_use]
pub fn position(&self) -> u64 {
self.position
}
#[inline(always)]
#[must_use]
pub fn inner_mut(&mut self) -> &mut S {
self.stream
}
#[inline]
pub fn restore(&mut self) -> Result<()> {
self.stream.seek_to(SeekFrom::Start(self.position)).map(|_| {
self.done = true;
})
}
#[inline(always)]
pub fn dismiss(mut self) {
self.done = true;
}
}
impl<S> Drop for PositionGuard<'_, S>
where
S: Seekable + ?Sized,
{
fn drop(&mut self) {
if !self.done {
drop(self.stream.seek_to(SeekFrom::Start(self.position)));
}
}
}