Implement strip_circumfix lib feature

This commit is contained in:
Yotam Ofek 2025-10-21 23:11:46 +03:00
parent 869fb4679f
commit 827bd00438
2 changed files with 68 additions and 0 deletions

View file

@ -2725,6 +2725,38 @@ impl<T> [T] {
None
}
/// Returns a subslice with the prefix and suffix removed.
///
/// If the slice starts with `prefix` and ends with `suffix`, returns the subslice after the
/// prefix and before the suffix, wrapped in `Some`.
///
/// If the slice does not start with `prefix` or does not end with `suffix`, returns `None`.
///
/// # Examples
///
/// ```
/// #![feature(strip_circumfix)]
///
/// let v = &[10, 50, 40, 30];
/// assert_eq!(v.strip_circumfix(&[10], &[30]), Some(&[50, 40][..]));
/// assert_eq!(v.strip_circumfix(&[10], &[40, 30]), Some(&[50][..]));
/// assert_eq!(v.strip_circumfix(&[10, 50], &[40, 30]), Some(&[][..]));
/// assert_eq!(v.strip_circumfix(&[50], &[30]), None);
/// assert_eq!(v.strip_circumfix(&[10], &[40]), None);
/// assert_eq!(v.strip_circumfix(&[], &[40, 30]), Some(&[10, 50][..]));
/// assert_eq!(v.strip_circumfix(&[10, 50], &[]), Some(&[40, 30][..]));
/// ```
#[must_use = "returns the subslice without modifying the original"]
#[unstable(feature = "strip_circumfix", issue = "147946")]
pub fn strip_circumfix<S, P>(&self, prefix: &P, suffix: &S) -> Option<&[T]>
where
T: PartialEq,
S: SlicePattern<Item = T> + ?Sized,
P: SlicePattern<Item = T> + ?Sized,
{
self.strip_prefix(prefix)?.strip_suffix(suffix)
}
/// Returns a subslice with the optional prefix removed.
///
/// If the slice starts with `prefix`, returns the subslice after the prefix. If `prefix`

View file

@ -2447,6 +2447,42 @@ impl str {
suffix.strip_suffix_of(self)
}
/// Returns a string slice with the prefix and suffix removed.
///
/// If the string starts with the pattern `prefix` and ends with the pattern `suffix`, returns
/// the substring after the prefix and before the suffix, wrapped in `Some`.
/// Unlike [`trim_start_matches`] and [`trim_end_matches`], this method removes both the prefix
/// and suffix exactly once.
///
/// If the string does not start with `prefix` or does not end with `suffix`, returns `None`.
///
/// Each [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a
/// function or closure that determines if a character matches.
///
/// [`char`]: prim@char
/// [pattern]: self::pattern
/// [`trim_start_matches`]: Self::trim_start_matches
/// [`trim_end_matches`]: Self::trim_end_matches
///
/// # Examples
///
/// ```
/// #![feature(strip_circumfix)]
///
/// assert_eq!("bar:hello:foo".strip_circumfix("bar:", ":foo"), Some("hello"));
/// assert_eq!("bar:foo".strip_circumfix("foo", "foo"), None);
/// assert_eq!("foo:bar;".strip_circumfix("foo:", ';'), Some("bar"));
/// ```
#[must_use = "this returns the remaining substring as a new slice, \
without modifying the original"]
#[unstable(feature = "strip_circumfix", issue = "147946")]
pub fn strip_circumfix<P: Pattern, S: Pattern>(&self, prefix: P, suffix: S) -> Option<&str>
where
for<'a> S::Searcher<'a>: ReverseSearcher<'a>,
{
self.strip_prefix(prefix)?.strip_suffix(suffix)
}
/// Returns a string slice with the optional prefix removed.
///
/// If the string starts with the pattern `prefix`, returns the substring after the prefix.