@@ -8,6 +8,7 @@ use crate::fmt;
88use crate :: hash:: { Hash , Hasher } ;
99use crate :: ops;
1010use crate :: rc:: Rc ;
11+ use crate :: str:: pattern:: Pattern ;
1112use crate :: str:: FromStr ;
1213use crate :: sync:: Arc ;
1314
@@ -1034,6 +1035,148 @@ impl OsStr {
10341035 pub fn eq_ignore_ascii_case < S : AsRef < OsStr > > ( & self , other : S ) -> bool {
10351036 self . inner . eq_ignore_ascii_case ( & other. as_ref ( ) . inner )
10361037 }
1038+
1039+ /// Returns `true` if the given pattern matches a prefix of this `OsStr`.
1040+ ///
1041+ /// Returns `false` if it does not.
1042+ ///
1043+ /// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a
1044+ /// function or closure that determines if a character matches.
1045+ ///
1046+ /// [`char`]: prim@char
1047+ /// [pattern]: crate::str::pattern
1048+ ///
1049+ /// # Examples
1050+ ///
1051+ /// Basic usage:
1052+ ///
1053+ /// ```
1054+ /// #![feature(osstr_str_prefix_ops)]
1055+ ///
1056+ /// use std::ffi::OsString;
1057+ ///
1058+ /// let bananas = OsString::from("bananas");
1059+ ///
1060+ /// assert!(bananas.starts_with("bana"));
1061+ /// assert!(!bananas.starts_with("nana"));
1062+ /// ```
1063+ #[ unstable( feature = "osstr_str_prefix_ops" , issue = "none" ) ]
1064+ #[ must_use]
1065+ #[ inline]
1066+ pub fn starts_with < ' a , P : Pattern < ' a > > ( & ' a self , pattern : P ) -> bool {
1067+ let ( p, _) = self . inner . to_str_split ( ) ;
1068+ p. starts_with ( pattern)
1069+ }
1070+
1071+ /// Returns `true` if the given `str` matches a prefix of this `OsStr`.
1072+ ///
1073+ /// Same as [`OsStr::starts_with`], but is easier to optimize to a
1074+ /// direct bitwise comparison.
1075+ ///
1076+ /// # Examples
1077+ ///
1078+ /// Basic usage:
1079+ ///
1080+ /// ```
1081+ /// #![feature(osstr_str_prefix_ops)]
1082+ ///
1083+ /// use std::ffi::OsString;
1084+ ///
1085+ /// let bananas = OsString::from("bananas");
1086+ ///
1087+ /// assert!(bananas.starts_with_str("bana"));
1088+ /// assert!(!bananas.starts_with_str("nana"));
1089+ /// ```
1090+ #[ unstable( feature = "osstr_str_prefix_ops" , issue = "none" ) ]
1091+ #[ must_use]
1092+ #[ inline]
1093+ pub fn starts_with_str ( & self , prefix : & str ) -> bool {
1094+ self . inner . starts_with_str ( prefix)
1095+ }
1096+
1097+ /// Returns this `OsStr` with the given prefix removed.
1098+ ///
1099+ /// If the `OsStr` starts with the pattern `prefix`, returns the substring
1100+ /// after the prefix, wrapped in `Some`.
1101+ ///
1102+ /// If the `OsStr` does not start with `prefix`, returns `None`.
1103+ ///
1104+ /// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a
1105+ /// function or closure that determines if a character matches.
1106+ ///
1107+ /// [`char`]: prim@char
1108+ /// [pattern]: crate::str::pattern
1109+ ///
1110+ /// # Examples
1111+ ///
1112+ /// ```
1113+ /// #![feature(osstr_str_prefix_ops)]
1114+ ///
1115+ /// use std::ffi::{OsStr, OsString};
1116+ ///
1117+ /// let foobar = OsString::from("foo:bar");
1118+ ///
1119+ /// assert_eq!(foobar.strip_prefix("foo:"), Some(OsStr::new("bar")));
1120+ /// assert_eq!(foobar.strip_prefix("bar"), None);
1121+ /// ```
1122+ #[ unstable( feature = "osstr_str_prefix_ops" , issue = "none" ) ]
1123+ #[ must_use]
1124+ #[ inline]
1125+ pub fn strip_prefix < ' a , P : Pattern < ' a > > ( & ' a self , prefix : P ) -> Option < & ' a OsStr > {
1126+ Some ( OsStr :: from_inner ( self . inner . strip_prefix ( prefix) ?) )
1127+ }
1128+
1129+ /// Returns this `OsStr` with the given prefix removed.
1130+ ///
1131+ /// Same as [`OsStr::strip_prefix`], but is easier to optimize to a
1132+ /// direct bitwise comparison.
1133+ ///
1134+ /// # Examples
1135+ ///
1136+ /// ```
1137+ /// #![feature(osstr_str_prefix_ops)]
1138+ ///
1139+ /// use std::ffi::{OsStr, OsString};
1140+ ///
1141+ /// let foobar = OsString::from("foo:bar");
1142+ ///
1143+ /// assert_eq!(foobar.strip_prefix("foo:"), Some(OsStr::new("bar")));
1144+ /// assert_eq!(foobar.strip_prefix_str("bar"), None);
1145+ /// ```
1146+ #[ unstable( feature = "osstr_str_prefix_ops" , issue = "none" ) ]
1147+ #[ must_use]
1148+ #[ inline]
1149+ pub fn strip_prefix_str ( & self , prefix : & str ) -> Option < & OsStr > {
1150+ Some ( OsStr :: from_inner ( self . inner . strip_prefix_str ( prefix) ?) )
1151+ }
1152+
1153+ /// Splits this `OsStr` on the first occurrence of the specified delimiter,
1154+ /// returning the prefix before delimiter and suffix after delimiter.
1155+ ///
1156+ /// The prefix is returned as a `str`, because a successful `Pattern` match
1157+ /// implies its matching prefix was valid Unicode.
1158+ ///
1159+ /// # Examples
1160+ ///
1161+ /// ```
1162+ /// #![feature(osstr_str_prefix_ops)]
1163+ ///
1164+ /// use std::ffi::{OsStr, OsString};
1165+ ///
1166+ /// let foo = OsString::from("foo:");
1167+ /// let foobar = OsString::from("foo:bar");
1168+ ///
1169+ /// assert_eq!(foo.split_once(':'), Some(("foo", OsStr::new(""))));
1170+ /// assert_eq!(foobar.split_once(':'), Some(("foo", OsStr::new("bar"))));
1171+ /// assert_eq!(foobar.split_once('='), None);
1172+ /// ```
1173+ #[ unstable( feature = "osstr_str_prefix_ops" , issue = "none" ) ]
1174+ #[ must_use]
1175+ #[ inline]
1176+ pub fn split_once < ' a , P : Pattern < ' a > > ( & ' a self , delimiter : P ) -> Option < ( & ' a str , & ' a OsStr ) > {
1177+ let ( before, after) = self . inner . split_once ( delimiter) ?;
1178+ Some ( ( before, OsStr :: from_inner ( after) ) )
1179+ }
10371180}
10381181
10391182#[ stable( feature = "box_from_os_str" , since = "1.17.0" ) ]
0 commit comments