Skip to content

Tracking Issue for io::Cursor::{split, split_mut} #86369

Open

Description

@soerenmeier

View all comments

Feature gate: #![feature(cursor_split)]

impl<T> Cursor<T>
where
    T: AsRef<[u8]>,
{
    pub fn split(&self) -> (&[u8], &[u8]);
}

impl<T> Cursor<T>
where
    T: AsMut<[u8]>,
{
    pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]);
}

Steps / History

Unresolved Questions/Issues

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on Jun 16, 2021
  2. added
    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`
    on Jun 16, 2021
  3. yaahc commented on Jun 16, 2021

    @yaahc
    Member

    One additional concern that @mystor pointed out is that stabilizing these APIs might prevent us from adding support to non-contiguous buffers/sets of buffers to Cursor in the future. The remaining method wouldn't translate, since it returns a single slice.

    We should be absolutely certain that we don't intend to extend Cursor this way in the future or we may wish to just stick with the usize returning version for now, since that one would have solved the original motivating example and it can be extended to work for multiple non-contiguous buffers.

  4. soerenmeier commented on Jun 16, 2021

    @soerenmeier
    ContributorAuthor

    Wouldn't that still work though? Since those contiguous buffers won't implement AsRef<[u8]>.
    To make it clear that this function only returns a slice we could rename it as suggested to remaining_slice and then the implementation for contiguous buffers could have a method named for example remaining_slices.

  5. yaahc commented on Jun 16, 2021

    @yaahc
    Member

    Wouldn't that still work though? Since those contiguous buffers won't implement AsRef<[u8]>.

    Oh, I had forgotten that remaining also had the as_ref bound. Yea, that should work fine.

    To make it clear that this function only returns a slice we could rename it as suggested to remaining_slice and then the implementation for contiguous buffers could have a method named for example remaining_slices.

    Sounds like a plan!

  6. soerenmeier commented on Jun 17, 2021

    @soerenmeier
    ContributorAuthor

    I renamed remaining to remaining_slice and added:

    fn remaining(&self) -> u64;

    Is that ok or should i remove it again?

  7. yaahc commented on Jun 17, 2021

    @yaahc
    Member

    Is that ok or should i remove it again?

    sounds great

  8. changed the title [-]Tracking Issue for `io::Cursor::{remaining, is_empty}`[/-] [+]Tracking Issue for `io::Cursor::{remaining, remaining_slice, is_empty}`[/+] on Jun 17, 2021
  9. added 2 commits that reference this issue on Jun 21, 2021
  10. seanmonstar commented on Jun 24, 2021

    @seanmonstar
    Contributor

    I'll just note that this change conflicts with bytes::Buf that is implemented for Cursor<impl AsRef<[u8]>>. The proposed remaining method here has a different signature, so shadowing won't work. While adding this method may be desired and ultimately the right decision (I haven't thought enough to say myself), it will have an impact on the ecosystem using bytes::Buf.

    I've also noticed an inconvenience that won't affect stable: since the method is "unstable" on nightly, it triggers an error, even though the trait is in scope.

  11. soerenmeier commented on Jun 24, 2021

    @soerenmeier
    ContributorAuthor

    That seems unfortunate. I'd be okay with changing the signature to return a usize, I chose u64 since position is u64 but since the underlying slice cannot be bigger than usize it would be possible to change the signature. The only point to consider is if support for non-contiguous buffers is added the length could be bigger than usize, but that also could be a problem with u64.

    About the error in nightly, I don't know how this is handled normally in std. But the impact should be rather small, since Cursor is only scarcely used, mostly in tests. Am I wrong?

  12. seanmonstar commented on Jun 25, 2021

    @seanmonstar
    Contributor

    I don't mean an error in libstd or it's test suite. But rather the greater ecosystem, anywhere using bytes::Buf and also running tests on nightly. For example, this PR for h2: hyperium/h2#547

  13. soerenmeier commented on Jun 25, 2021

    @soerenmeier
    ContributorAuthor

    I didn't either. I meant the use of Cursor in combination with bytes::Buf on nightly calling remaining. After your first comment i made a few short searches concluding with the statement above, interpreting your reaction, that was probably the wrong assessment. Imho failing nightly tests should be acceptable but addressed (if stable is the target).
    Do you have a suggestion to solve this?

  14. 17 remaining items

  15. m-ou-se commented on Oct 27, 2021

    @m-ou-se
    Member

    If we have an is_empty method, we probably should have a len method. (And it looks like that's what remaining was before it was removed. So I wonder whether that should be added back as len.)

    Note that the length of the underlying buffer doesn't change when reading or writing or seeking through it. The only thing that changes is the position of the cursor, and the bytes in the buffer (when writing). (E.g. seeking to the beginning will 'unempty' it and produce the already read data again.)

  16. jkugelman commented on Oct 28, 2021

    @jkugelman
    Contributor

    I really like that, looking at the cursor symmetrically. You're talking about something like this?

    pub struct Cursor<T> {
        pub fn remaining(&self) -> &[u8];
        pub fn remaining_mut(&mut self) -> &mut [u8];
        pub fn preceding(&self) -> &[u8];
        pub fn preceding_mut(&mut self) -> &mut [u8];
        pub fn split_at(&self) -> (&[u8], &[u8]);
        pub fn split_at_mut(&mut self) -> (&mut [u8], &mut [u8]);
    }
  17. m-ou-se commented on Jan 12, 2022

    @m-ou-se
    Member

    It doesn't look like this will go through in its current form, so I'm cancelling the proposed FCP.

    @rfcbot cancel

    @jkugelman Yeah, something like that. Or before_cursor, after_cursor and split_at_cursor or something in that direction. As long as it makes sense from both a Read and Write perspective (+Seek).

  18. rfcbot commented on Jan 12, 2022

    @rfcbot

    @m-ou-se proposal cancelled.

  19. removed
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    on Jan 12, 2022
  20. glandium commented on Jul 8, 2022

    @glandium
    Contributor

    Stumbled upon these functions today. Considering the concerns, would it be worth removing the current implementation?

  21. soerenmeier commented on Jul 8, 2022

    @soerenmeier
    ContributorAuthor

    I once made a commit with possible alternatives but wasn't sure about if the implementation should not be generic over T: AsRef<[u8]>. That would allow to return different lifetimes for example for Cursor<&'a [u8]> so the function could look like fn split(&self) -> (&'a [u8], &'a [u8]);. That was one concern raised in #86369 (comment).

    My Implementation was based on these functions:

    fn split(&self) -> (&[u8], &[u8]);
    fn before(&self) -> &[u8];
    fn after(&self) -> &[u8];
    fn split_mut(&mut self) -> (&mut [u8], &mut [u8]);
    fn before_mut(&mut self) -> &mut [u8];
    fn after_mut(&mut self) -> &mut [u8];

    Commit: soerenmeier@eab83e3

  22. changed the title [-]Tracking Issue for `io::Cursor::{remaining_slice, is_empty}`[/-] [+]Tracking Issue for `io::Cursor::{split, split_mut}`[/+] on Jul 28, 2024
  23. added a commit that references this issue on Jul 28, 2024
  24. added a commit that references this issue on Jul 29, 2024
  25. added a commit that references this issue on Jul 29, 2024
  26. added a commit that references this issue on Mar 11, 2025
  27. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions