-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize strip_prefix and strip_suffix with str patterns #69784
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
#![stable(feature = "rust1", since = "1.0.0")] | ||
|
||
use self::pattern::Pattern; | ||
use self::pattern::{DoubleEndedSearcher, ReverseSearcher, SearchStep, Searcher}; | ||
use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher}; | ||
|
||
use crate::char; | ||
use crate::fmt::{self, Write}; | ||
|
@@ -3986,26 +3986,15 @@ impl str { | |
/// ``` | ||
/// #![feature(str_strip)] | ||
/// | ||
/// assert_eq!("foobar".strip_prefix("foo"), Some("bar")); | ||
/// assert_eq!("foobar".strip_prefix("bar"), None); | ||
/// assert_eq!("foo:bar".strip_prefix("foo:"), Some("bar")); | ||
/// assert_eq!("foo:bar".strip_prefix("bar"), None); | ||
/// assert_eq!("foofoo".strip_prefix("foo"), Some("foo")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be updated to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The intent of this test case, as best as I can tell, is to check that |
||
/// ``` | ||
#[must_use = "this returns the remaining substring as a new slice, \ | ||
without modifying the original"] | ||
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")] | ||
pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> { | ||
let mut matcher = prefix.into_searcher(self); | ||
if let SearchStep::Match(start, len) = matcher.next() { | ||
debug_assert_eq!( | ||
start, 0, | ||
"The first search step from Searcher \ | ||
must include the first character" | ||
); | ||
// SAFETY: `Searcher` is known to return valid indices. | ||
unsafe { Some(self.get_unchecked(len..)) } | ||
} else { | ||
None | ||
} | ||
prefix.strip_prefix_of(self) | ||
} | ||
|
||
/// Returns a string slice with the suffix removed. | ||
|
@@ -4020,8 +4009,8 @@ impl str { | |
/// | ||
/// ``` | ||
/// #![feature(str_strip)] | ||
/// assert_eq!("barfoo".strip_suffix("foo"), Some("bar")); | ||
/// assert_eq!("barfoo".strip_suffix("bar"), None); | ||
/// assert_eq!("bar:foo".strip_suffix(":foo"), Some("bar")); | ||
/// assert_eq!("bar:foo".strip_suffix("bar"), None); | ||
/// assert_eq!("foofoo".strip_suffix("foo"), Some("foo")); | ||
/// ``` | ||
#[must_use = "this returns the remaining substring as a new slice, \ | ||
|
@@ -4032,19 +4021,7 @@ impl str { | |
P: Pattern<'a>, | ||
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>, | ||
{ | ||
let mut matcher = suffix.into_searcher(self); | ||
if let SearchStep::Match(start, end) = matcher.next_back() { | ||
debug_assert_eq!( | ||
end, | ||
self.len(), | ||
"The first search step from ReverseSearcher \ | ||
must include the last character" | ||
); | ||
// SAFETY: `Searcher` is known to return valid indices. | ||
unsafe { Some(self.get_unchecked(..start)) } | ||
} else { | ||
None | ||
} | ||
suffix.strip_suffix_of(self) | ||
} | ||
|
||
/// Returns a string slice with all suffixes that match a pattern | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering - do these changes improve the test cases or are they simply to make the docs more readable? Or some other thing? I assume it's not because the previous tests failed with the new implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They improve the test cases to account for a bug that I introduced while rewriting these methods that was not properly caught by the old test cases. The old test cases had the defect that they split the string exactly in half. My buggy implementation for
strip_suffix
sliced froms[pat.len()..]
when it needed to slice froms[s.len() - pat.len()..]
, which was not caught by any of the previous test cases.