oct 0.26.0

Octonary transcodings.
Documentation
// Copyright 2024-2025 Gabriel Bjørnager Jensen.
//
// This Source Code Form is subject to the terms of
// the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, you
// can obtain one at:
// <https://mozilla.org/MPL/2.0/>.

//! The [`Seek`] trait.

use crate::io::{Result, SeekFrom};

#[cfg(feature = "alloc")]
use alloc::boxed::Box;

#[cfg(feature = "std")]
use std::fs::File;

#[cfg(feature = "std")]
use std::io::{BufReader, BufWriter};

#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
use alloc::sync::Arc;

/// Denotes a type that cen be seeked within.
pub trait Seek {
	/// Seeks according to the specified mode.
	///
	/// # Errors
	///
	/// This method should return an [`Err`] instance
	/// if the specified mode is either invalid or
	/// impossible to perform. Any mode that results in
	/// a negative position is considered invalid.
	fn seek(&mut self, mode: SeekFrom) -> Result<u64>;

	/// Resets the position of the stream.
	///
	/// # Errors
	///
	/// This method should return an [`Err`] instance
	/// if the stream could not be rewound.
	#[inline]
	fn rewind(&mut self) -> Result<()> {
		self.seek(SeekFrom::Start(0))?;
		Ok(())
	}

	/// Seeks with an offset relative to the current
	/// position.
	///
	/// # Errors
	///
	/// This method should return an [`Err`] instance
	/// if the specified offset is either invalid or
	/// impossible to seek to. Any offset that results
	/// in a negative position is considered invalid.
	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		self.seek(SeekFrom::Current(offset))?;
		Ok(())
	}

	/// Retrieves the current position in the octet
	/// stream.
	///
	/// # Errors
	///
	/// This method should return an [`Err`] instance
	/// if current position has become invalid.
	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = self.seek(SeekFrom::Current(0))?;
		Ok(position)
	}
}

#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
impl Seek for Arc<File> {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "alloc")]
impl<S: ?Sized + Seek> Seek for Box<S> {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = S::seek(self, mode)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl<S: ?Sized + std::io::Seek> Seek for BufReader<S> {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl<S: ?Sized + std::io::Write + std::io::Seek> Seek for BufWriter<S> {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl<T: AsRef<[u8]>> Seek for std::io::Cursor<T> {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl Seek for std::io::Empty {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl Seek for File {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

#[cfg(feature = "std")]
impl Seek for &File {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		let position = std::io::Seek::seek(self, mode.into())?;
		Ok(position)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		std::io::Seek::rewind(self)?;
		Ok(())
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		std::io::Seek::seek_relative(self, offset)?;
		Ok(())
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		let position = std::io::Seek::stream_position(self)?;
		Ok(position)
	}
}

// SORT: reference
impl<S: Seek> Seek for &mut S {
	#[inline]
	fn seek(&mut self, mode: SeekFrom) -> Result<u64> {
		S::seek(self, mode)
	}

	#[inline]
	fn rewind(&mut self) -> Result<()> {
		S::rewind(self)
	}

	#[inline]
	fn seek_relative(&mut self, offset: i64) -> Result<()> {
		S::seek_relative(self, offset)
	}

	#[inline]
	fn stream_position(&mut self) -> Result<u64> {
		S::stream_position(self)
	}
}