Skip to content

Commit

Permalink
Rollup merge of rust-lang#116750 - fintelia:seek_seek_relative, r=Mar…
Browse files Browse the repository at this point in the history
…k-Simulacrum

Add Seek::seek_relative

The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100).

Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation.

_Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
  • Loading branch information
TaKO8Ki authored Nov 18, 2023
2 parents f21f28c + d9f7c9d commit ad71725
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
10 changes: 10 additions & 0 deletions library/std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,16 @@ impl<R: ?Sized + Seek> Seek for BufReader<R> {
)
})
}

/// Seeks relative to the current position.
///
/// If the new position lies within the buffer, the buffer will not be
/// flushed, allowing for more efficient seeks. This method does not return
/// the location of the underlying reader, so the caller must track this
/// information themselves if it is required.
fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
self.seek_relative(offset)
}
}

impl<T: ?Sized> SizeHint for BufReader<T> {
Expand Down
30 changes: 30 additions & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,36 @@ pub trait Seek {
fn stream_position(&mut self) -> Result<u64> {
self.seek(SeekFrom::Current(0))
}

/// Seeks relative to the current position.
///
/// This is equivalent to `self.seek(SeekFrom::Current(offset))` but
/// doesn't return the new position which can allow some implementations
/// such as [`BufReader`] to perform more efficient seeks.
///
/// # Example
///
/// ```no_run
/// #![feature(seek_seek_relative)]
/// use std::{
/// io::{self, Seek},
/// fs::File,
/// };
///
/// fn main() -> io::Result<()> {
/// let mut f = File::open("foo.txt")?;
/// f.seek_relative(10)?;
/// assert_eq!(f.stream_position()?, 10);
/// Ok(())
/// }
/// ```
///
/// [`BufReader`]: crate::io::BufReader
#[unstable(feature = "seek_seek_relative", issue = "117374")]
fn seek_relative(&mut self, offset: i64) -> Result<()> {
self.seek(SeekFrom::Current(offset))?;
Ok(())
}
}

/// Enumeration of possible methods to seek within an I/O object.
Expand Down

0 comments on commit ad71725

Please sign in to comment.