@@ -45,10 +45,17 @@ use std::borrow::Cow;
45
45
use std:: ffi:: OsStr ;
46
46
47
47
#[ derive( Debug ) ]
48
- /// The error type returned by [`into_bytes()`] which would otherwise return `OsString`,
49
- /// which is not an error.
48
+ /// The error type returned by [`into_bytes()`] and others may suffer from failed conversions from or to bytes.
50
49
pub struct Utf8Error ;
51
50
51
+ impl std:: fmt:: Display for Utf8Error {
52
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
53
+ f. write_str ( "Could not convert to UTF8 or from UTF8 due to ill-formed input" )
54
+ }
55
+ }
56
+
57
+ impl std:: error:: Error for Utf8Error { }
58
+
52
59
/// Like [`into_bytes()`], but takes `OsStr` as input for a lossless, but fallible, conversion.
53
60
pub fn os_str_into_bytes ( path : & OsStr ) -> Result < & [ u8 ] , Utf8Error > {
54
61
let path = into_bytes ( Cow :: Borrowed ( path. as_ref ( ) ) ) ?;
@@ -99,19 +106,19 @@ pub fn into_bytes_or_panic_on_windows<'a>(path: impl Into<Cow<'a, Path>>) -> Cow
99
106
/// On windows, the input is required to be valid UTF-8, which is guaranteed if we wrote it before. There are some potential
100
107
/// git versions and windows installation which produce mal-formed UTF-16 if certain emojies are in the path. It's as rare as
101
108
/// it sounds, but possible.
102
- pub fn from_byte_slice ( input : & [ u8 ] ) -> Option < & Path > {
109
+ pub fn from_byte_slice ( input : & [ u8 ] ) -> Result < & Path , Utf8Error > {
103
110
#[ cfg( unix) ]
104
111
let p = {
105
112
use std:: os:: unix:: ffi:: OsStrExt ;
106
113
OsStr :: from_bytes ( input) . as_ref ( )
107
114
} ;
108
115
#[ cfg( not( unix) ) ]
109
- let p = Path :: new ( std:: str:: from_utf8 ( input) . ok ( ) ?) ;
110
- Some ( p)
116
+ let p = Path :: new ( std:: str:: from_utf8 ( input) . map_err ( |_| Utf8Error ) ?) ;
117
+ Ok ( p)
111
118
}
112
119
113
120
/// Similar to [`from_byte_slice()`], but takes either borrowed or owned `input`.
114
- pub fn from_bytes < ' a > ( input : impl Into < Cow < ' a , [ u8 ] > > ) -> Option < Cow < ' a , Path > > {
121
+ pub fn from_bytes < ' a > ( input : impl Into < Cow < ' a , [ u8 ] > > ) -> Result < Cow < ' a , Path > , Utf8Error > {
115
122
let input = input. into ( ) ;
116
123
match input {
117
124
Cow :: Borrowed ( input) => from_byte_slice ( input) . map ( Cow :: Borrowed ) ,
@@ -121,7 +128,7 @@ pub fn from_bytes<'a>(input: impl Into<Cow<'a, [u8]>>) -> Option<Cow<'a, Path>>
121
128
122
129
/// Similar to [`from_byte_slice()`], but takes either borrowed or owned `input` as bstr.
123
130
#[ cfg( feature = "bstr" ) ]
124
- pub fn from_bstr < ' a > ( input : impl Into < Cow < ' a , bstr:: BStr > > ) -> Option < Cow < ' a , Path > > {
131
+ pub fn from_bstr < ' a > ( input : impl Into < Cow < ' a , bstr:: BStr > > ) -> Result < Cow < ' a , Path > , Utf8Error > {
125
132
let input = input. into ( ) ;
126
133
match input {
127
134
Cow :: Borrowed ( input) => from_byte_slice ( input) . map ( Cow :: Borrowed ) ,
@@ -130,16 +137,16 @@ pub fn from_bstr<'a>(input: impl Into<Cow<'a, bstr::BStr>>) -> Option<Cow<'a, Pa
130
137
}
131
138
132
139
/// Similar to [`from_byte_slice()`], but takes and produces owned data.
133
- pub fn from_byte_vec ( input : impl Into < Vec < u8 > > ) -> Option < PathBuf > {
140
+ pub fn from_byte_vec ( input : impl Into < Vec < u8 > > ) -> Result < PathBuf , Utf8Error > {
134
141
let input = input. into ( ) ;
135
142
#[ cfg( unix) ]
136
143
let p = {
137
144
use std:: os:: unix:: ffi:: OsStringExt ;
138
145
std:: ffi:: OsString :: from_vec ( input) . into ( )
139
146
} ;
140
147
#[ cfg( not( unix) ) ]
141
- let p = PathBuf :: from ( String :: from_utf8 ( input) . ok ( ) ?) ;
142
- Some ( p)
148
+ let p = PathBuf :: from ( String :: from_utf8 ( input) . map_err ( |_| Utf8Error ) ?) ;
149
+ Ok ( p)
143
150
}
144
151
145
152
/// Similar to [`from_byte_vec()`], but will panic if there is ill-formed UTF-8 in the `input`.
0 commit comments