@@ -2,6 +2,9 @@ use crate::ffi::OsStr;
22use crate :: mem;
33use crate :: path:: Prefix ;
44
5+ #[ cfg( test) ]
6+ mod tests;
7+
58pub const MAIN_SEP_STR : & str = "\\ " ;
69pub const MAIN_SEP : char = '\\' ;
710
@@ -43,7 +46,7 @@ pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
4346 if let Some ( path) = path. strip_prefix ( br"?\" ) {
4447 // \\?\UNC\server\share
4548 if let Some ( path) = path. strip_prefix ( br"UNC\" ) {
46- let ( server, share) = match parse_two_comps ( path, is_verbatim_sep) {
49+ let ( server, share) = match get_first_two_components ( path, is_verbatim_sep) {
4750 Some ( ( server, share) ) => {
4851 ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) )
4952 }
@@ -71,7 +74,7 @@ pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
7174 let slice = & path[ ..idx] ;
7275 return Some ( DeviceNS ( u8_slice_as_os_str ( slice) ) ) ;
7376 }
74- match parse_two_comps ( path, is_sep_byte) {
77+ match get_first_two_components ( path, is_sep_byte) {
7578 Some ( ( server, share) ) if !server. is_empty ( ) && !share. is_empty ( ) => {
7679 // \\server\share
7780 return Some ( UNC ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) ) ) ;
@@ -86,13 +89,20 @@ pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
8689 }
8790 return None ;
8891 }
89-
90- fn parse_two_comps ( mut path : & [ u8 ] , f : fn ( u8 ) -> bool ) -> Option < ( & [ u8 ] , & [ u8 ] ) > {
91- let first = & path[ ..path. iter ( ) . position ( |x| f ( * x) ) ?] ;
92- path = & path[ ( first. len ( ) + 1 ) ..] ;
93- let idx = path. iter ( ) . position ( |x| f ( * x) ) ;
94- let second = & path[ ..idx. unwrap_or ( path. len ( ) ) ] ;
95- Some ( ( first, second) )
96- }
9792}
9893
94+ /// Returns the first two path components with predicate `f`.
95+ ///
96+ /// The two components returned will be use by caller
97+ /// to construct `VerbatimUNC` or `UNC` Windows path prefix.
98+ ///
99+ /// Returns [`None`] if there are no separators in path.
100+ fn get_first_two_components ( path : & [ u8 ] , f : fn ( u8 ) -> bool ) -> Option < ( & [ u8 ] , & [ u8 ] ) > {
101+ let idx = path. iter ( ) . position ( |& x| f ( x) ) ?;
102+ // Panic safe
103+ // The max `idx+1` is `path.len()` and `path[path.len()..]` is a valid index.
104+ let ( first, path) = ( & path[ ..idx] , & path[ idx + 1 ..] ) ;
105+ let idx = path. iter ( ) . position ( |& x| f ( x) ) . unwrap_or ( path. len ( ) ) ;
106+ let second = & path[ ..idx] ;
107+ Some ( ( first, second) )
108+ }
0 commit comments