rust-lang / rust-lang/libs-team

APC: split_pattern on slices

Open
#457 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

api-change-proposal
Dominant language
Rust
Stars
178
Forks
28
Avg merge
15m
Merged PRs (30d)
1

Description

Proposal

Add a split_pattern on slices, which is similar to split on slices but takes a slice instead of a closure, and splits the first slice on every instance of the provided pattern slice.

Problem statement

Inspiration was taken from https://github.com/rust-lang/rust/issues/49036, which basically suggests extending the existing String::split to a more generic slice::split_pattern which was implemented for any T: PartialEq, and maybe a Vec::split_pattern as well.

Motivating examples or use cases

From the original issue, suppose you have a Vec<u8> of non-UTF8 data and you want to split on newlines, it would be very nice to be able so simply my_vec.split_pattern(b"\n"), instead of my_vec.split(|x| *x == b'\n'). The closure on split is way clunkier when you want to match on multi-element patterns, since split runs the closure for one given element, not a slice.

Solution sketch

I didn't know about APCs, so I made a PR before this with an idea of how it could be implemented for slices, with the following struct:

pub struct SplitPattern<'a, 'b, T>
where
    T: cmp::PartialEq,
{
    v: &'a [T],
    pattern: &'b [T],
    finished: bool,
}

and the most important method:

impl<'a, 'b, T> Iterator for SplitPattern<'a, 'b, T>
where
    T: cmp::PartialEq,
{
    type Item = &'a [T];

    #[inline]
    fn next(&mut self) -> Option<&'a [T]> {
        if self.finished {
            return None;
        }

        for i in 0..self.v.len() {
            if self.v[i..].starts_with(&self.pattern) {
                let (left, right) = (&self.v[0..i], &self.v[i + self.pattern.len()..]);
                let ret = Some(left);
                self.v = right;
                return ret;
            }
        }
        self.finish()
    }
}

next_back would be implemented similarly using ends_with instead of starts_with.

The implementation for Vec would be pretty similar I think.

Alternatives

I read about SlicePattern, however the source comments said something about generalising core::str::Pattern so I wasn't sure if I should use it or not, and I also thought that doing that would be a little out of my range.

Links and related work

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the existing slice split API and the SlicePattern source comments mentioned in the issue. Review the implementation direction in rust-lang/rust PR 131340, then determine whether the proposed slice and Vec APIs fit the project’s existing patterns. Done means an agreed API and implementation scope for splitting on multi-element patterns.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.