# Add \`Seek::seek\_relative\`?

**URL:** <https://internals.rust-lang.org/t/add-seek-seek-relative/19546>\
**Category:** libs\
**Created:** [September 10, 2023, 7:48pm UTC](https://internals.rust-lang.org/t/add-seek-seek-relative/19546 "2023-09-10T19:48:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![fintelia](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fintelia/32/3558_2.png) [@fintelia](https://internals.rust-lang.org/u/fintelia)\
**Post date:** [September 10, 2023, 7:48pm UTC](https://internals.rust-lang.org/t/add-seek-seek-relative/19546/1 "2023-09-10T19:48:31Z")

</div>

`BufReader::seek_relative` was added to address [#31100](https://github.com/rust-lang/rust/issues/31100). As explained in that issue, `BufReader`'s stable API required that the internal buffer was dumped on any call to `seek`, so the new method was added to expose a way to seek without doing dumping the buffer.

Unfortunately, there isn't really a good way to take advantage of the method in generic code. If a method takes a `R: Read + Seek`, then only the regular (inefficient) seek implementation is exposed. The method could itself create a `BufReader<R>` and then call `seek_relative`, but then depending on what R is, it might end up making a `BufReader<BufReader<File>>` or `BufReader<Cursor<Vec<u8>>>` or some other silly type.

If the `Seek` trait had a `seek_relative` method (with the straightforward implementation as a default impl) then this could be solved.

---

<div class="post-metadata">

**Author:** ![ZyX-I](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zyx-i/32/11398_2.png) [@ZyX-I](https://internals.rust-lang.org/u/ZyX-I)\
**Post date:** [September 10, 2023, 8:52pm UTC](https://internals.rust-lang.org/t/add-seek-seek-relative/19546/2 "2023-09-10T20:52:42Z")

</div>

Would not that require then teaching everybody to use `seek_relative` for more performant seeks? I think it makes more sense to add a newtype wrapper (or encode relative seek strategy at type level via some other means like extra type parameter to `BufReader` with default value) which changes relative seek strategy so that existing generic code does not need to be modified: it is not like code accepting `R: Read + Seek` can call `BufReader::into_inner` after seeking which as far as I understand was the sole reason existing behaviour was preserved.

Actually in my opinion it would have made more sense to encode relative seek strategy at type level when `seek_relative` was introduced and add function(s) to change type instead, but that ship has sailed. Still possible to add that parameter and `sync_with_inner()` (to achieve what `seek(SeekFrom::Current(0))` currently does regardless of relative seek strategy in code which does know it has `BufReader`, but does not want to restrict strategy) though, that just can create confusion.

---

<div class="post-metadata">

**Author:** ![fintelia](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fintelia/32/3558_2.png) [@fintelia](https://internals.rust-lang.org/u/fintelia)\
**Post date:** [September 10, 2023, 9:21pm UTC](https://internals.rust-lang.org/t/add-seek-seek-relative/19546/3 "2023-09-10T21:21:39Z")

</div>

The `BufReader::seek` gotcha already exists and I think the ship has long since sailed on preventing it. As a result, we already have to teach everybody about `BufReader::seek_relative`.

My proposal would not require any new action from _end users_. They already have to know about wrapping file accesses in a `BufReader`, but wouldn't have to make any other changes to their code. _Library authors_ whose code does a lot of seeks would however gain a new tool to work around the gotcha.

On the other hand, creating a wrapper type or an extra type parameter on `BufReader` would require action by end users. Specifically, they'd have to be the ones to decide to use the wrapper type based on a guess that the library function they're calling will do a lot of seeks.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [December 9, 2023, 9:22pm UTC](https://internals.rust-lang.org/t/add-seek-seek-relative/19546/4 "2023-12-09T21:22:07Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
