# \`str::actually\_strip\_prefix\`

**URL:** <https://internals.rust-lang.org/t/str-actually-strip-prefix/13946>\
**Category:** libs\
**Created:** [January 31, 2021, 3:28pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946 "2021-01-31T15:28:21Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [January 31, 2021, 3:28pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/1 "2021-01-31T15:28:21Z")

</div>

We'd like to add:

```rust
pub fn actually_strip_prefix<'a, P: Pattern<'a>>(&mut &'a self, prefix: P) -> bool {
  if let Some(v) = self.strip_prefix(prefix) {
    *self = v;
    true
  } else {
    false
  }
}

```

to `str`, as well as `actually_strip_suffix`. Thoughts?

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 31, 2021, 4:02pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/2 "2021-01-31T16:02:16Z")

</div>

I don’t know.. `&mut &'a str` seems weird; I’ve only seen something like this in places where a trait requires this kind of pattern, e.g. the signature of `read` in [`impl Read for &[u8]`](https://doc.rust-lang.org/std/io/trait.Read.html#impl-Read-10). Also, you aren’t serious about the name including “actually”, are you?

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [January 31, 2021, 4:21pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/3 "2021-01-31T16:21:23Z")

</div>

`&mut &str` doesn't bother me particularly, though the syntax for the `self` argument would need to change to `self: &mut &'a Self` (or it could take `&mut self` and be implemented on `&'a str`).

My one concern with this besides finding a good name would be the following trap that new programmers might fall into while trying to figure out how to use this on a `String`:

```rust
fn foo(mut s: String) {
    s.as_str().actually_strip_prefix("bar"); // does nothing
}

```

(It's really easy to create, modify, and drop a temporary `&str` without realizing it.)

---

<div class="post-metadata">

**Author:** ![birkenfeld](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/birkenfeld/32/1150_2.png) [@birkenfeld](https://internals.rust-lang.org/u/birkenfeld)\
**Post date:** [January 31, 2021, 4:34pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/4 "2021-01-31T16:34:37Z")

</div>

There's two ways to design this API - in-place or not. Rust chose to make it not in-place and there is no good reason to add the second one as well, to everyone's confusion.

---

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [January 31, 2021, 4:48pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/5 "2021-01-31T16:48:04Z")

</div>

You could name it something like `strip_prefix_in_place` but...

```rust
s.strip_prefix_in_place(prefix);

```

vs

```rust
s = s.strip_prefix(prefix);

```

The latter is shorter to type, so I don't see how the former is actually beneficial.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 31, 2021, 4:55pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/6 "2021-01-31T16:55:23Z")

</div>

> [@bascule](#):
>
> `s = s.strip_prefix(prefix);`

Well, that’s not the correct workaround. More like

```rust
s = s.strip_prefix(prefix).unwrap_or(s);

```

and that doesn’t “remember” if some prefix was actually found and stripped, either.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 31, 2021, 5:01pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/7 "2021-01-31T17:01:24Z")

</div>

> [@mbrubeck](#):
>
> (It's really easy to create, modify, and drop a temporary `&str` without realizing it.)

There’s a similar thought behind lots of iterators, e.g. [`slice::Iter`](https://doc.rust-lang.org/std/slice/struct.Iter.html), not being `Copy`, even though they could be. It’s too easy to accidentally mutate a copy and expect the original value to have changed. On the other hand, `&str` _does_ already implement `Copy`, so to avoid the same problem it’s better to avoid having `&mut &str` parameters.

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [January 31, 2021, 5:55pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/8 "2021-01-31T17:55:04Z")

</div>

Perhaps it might be useful to have something like

```
split_prefix<'a>(self: &'a str, prefix: impl Pattern<'a>)
    -> (Option<&'a str>, &'a str)

```

(basically like `split_once` but divides the string into a (match, rest) pair). Would be a good building block for eg. writing simple one-off parsers as well as making OP's use case fairly ergonomic.

Might also have been better for `strip_prefix` return a `(bool, &str)` rather than `Option` but that ship has obviously sailed.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [January 31, 2021, 9:54pm UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/9 "2021-01-31T21:54:59Z")

</div>

It's not really in-place tho.

It uses nested references.

... Hey maybe the lack of a good name is a good reason to avoid doing it.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [February 1, 2021, 5:02am UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/10 "2021-02-01T05:02:13Z")

</div>

Confirming this is useful for writing parsers. I recently wrote code that definitely could've used this API, as I functionally did the same thing myself.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [March 7, 2021, 3:24am UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/11 "2021-03-07T03:24:38Z")

</div>

To be completely honest, it turns out having `try {}` would work a lot better here.

---

<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:** [June 5, 2021, 3:25am UTC](https://internals.rust-lang.org/t/str-actually-strip-prefix/13946/12 "2021-06-05T03:25:34Z")

</div>

Closed on June 5, 2021, 3:25am UTC

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