3636 doc = include_str!( "../README.md" )
3737) ]
3838
39- use std:: ffi:: { OsStr , OsString } ;
40- use std:: path:: { Path , PathBuf } ;
41-
4239mod ascii;
4340mod bash;
4441mod fish;
@@ -176,22 +173,6 @@ impl<'a> From<&'a String> for Quotable<'a> {
176173 }
177174}
178175
179- #[ cfg( unix) ]
180- impl < ' a > From < & ' a OsStr > for Quotable < ' a > {
181- fn from ( source : & ' a OsStr ) -> Quotable < ' a > {
182- use std:: os:: unix:: ffi:: OsStrExt ;
183- source. as_bytes ( ) . into ( )
184- }
185- }
186-
187- #[ cfg( unix) ]
188- impl < ' a > From < & ' a OsString > for Quotable < ' a > {
189- fn from ( source : & ' a OsString ) -> Quotable < ' a > {
190- use std:: os:: unix:: ffi:: OsStrExt ;
191- source. as_bytes ( ) . into ( )
192- }
193- }
194-
195176#[ cfg( feature = "bstr" ) ]
196177impl < ' a > From < & ' a bstr:: BStr > for Quotable < ' a > {
197178 fn from ( source : & ' a bstr:: BStr ) -> Quotable < ' a > {
@@ -208,16 +189,99 @@ impl<'a> From<&'a bstr::BString> for Quotable<'a> {
208189 }
209190}
210191
192+ // ----------------------------------------------------------------------------
193+
194+ /// Unix-specific support.
211195#[ cfg( unix) ]
212- impl < ' a > From < & ' a Path > for Quotable < ' a > {
213- fn from ( source : & ' a Path ) -> Quotable < ' a > {
214- source. as_os_str ( ) . into ( )
196+ mod platform {
197+ use std:: ffi:: { OsStr , OsString } ;
198+ use std:: path:: { Path , PathBuf } ;
199+
200+ use super :: Quotable ;
201+
202+ impl < ' a > From < & ' a OsStr > for Quotable < ' a > {
203+ fn from ( source : & ' a OsStr ) -> Quotable < ' a > {
204+ use std:: os:: unix:: ffi:: OsStrExt ;
205+ source. as_bytes ( ) . into ( )
206+ }
207+ }
208+
209+ impl < ' a > From < & ' a OsString > for Quotable < ' a > {
210+ fn from ( source : & ' a OsString ) -> Quotable < ' a > {
211+ use std:: os:: unix:: ffi:: OsStrExt ;
212+ source. as_bytes ( ) . into ( )
213+ }
214+ }
215+
216+ impl < ' a > From < & ' a Path > for Quotable < ' a > {
217+ fn from ( source : & ' a Path ) -> Quotable < ' a > {
218+ source. as_os_str ( ) . into ( )
219+ }
220+ }
221+
222+ impl < ' a > From < & ' a PathBuf > for Quotable < ' a > {
223+ fn from ( source : & ' a PathBuf ) -> Quotable < ' a > {
224+ source. as_os_str ( ) . into ( )
225+ }
215226 }
216227}
217228
218- #[ cfg( unix) ]
219- impl < ' a > From < & ' a PathBuf > for Quotable < ' a > {
220- fn from ( source : & ' a PathBuf ) -> Quotable < ' a > {
221- source. as_os_str ( ) . into ( )
229+ // ----------------------------------------------------------------------------
230+
231+ #[ cfg( windows) ]
232+ pub use platform:: UnicodeError ;
233+
234+ /// Windows-specific support.
235+ #[ cfg( windows) ]
236+ mod platform {
237+ use std:: ffi:: { OsStr , OsString } ;
238+ use std:: path:: { Path , PathBuf } ;
239+
240+ use super :: Quotable ;
241+
242+ /// Error when converting an [`OsStr`]/[`OsString`] that contains invalid
243+ /// Unicode, e.g. unpaired UTF-16 surrogates on Windows.
244+ #[ derive( Debug , Clone ) ]
245+ #[ non_exhaustive]
246+ pub struct UnicodeError { }
247+
248+ impl std:: error:: Error for UnicodeError { }
249+
250+ impl std:: fmt:: Display for UnicodeError {
251+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
252+ write ! ( f, "invalid Unicode (unpaired UTF-16 surrogates)" )
253+ }
254+ }
255+
256+ impl < ' a > TryFrom < & ' a OsStr > for Quotable < ' a > {
257+ type Error = UnicodeError ;
258+
259+ fn try_from ( source : & ' a OsStr ) -> Result < Self , Self :: Error > {
260+ source. to_str ( ) . map ( Quotable :: Text ) . ok_or ( UnicodeError { } )
261+ }
262+ }
263+
264+ impl < ' a > TryFrom < & ' a OsString > for Quotable < ' a > {
265+ type Error = UnicodeError ;
266+
267+ fn try_from ( source : & ' a OsString ) -> Result < Self , Self :: Error > {
268+ source. as_os_str ( ) . try_into ( )
269+ }
270+ }
271+
272+ impl < ' a > TryFrom < & ' a Path > for Quotable < ' a > {
273+ type Error = UnicodeError ;
274+
275+ fn try_from ( source : & ' a Path ) -> Result < Self , Self :: Error > {
276+ source. as_os_str ( ) . try_into ( )
277+ }
278+ }
279+
280+ impl < ' a > TryFrom < & ' a PathBuf > for Quotable < ' a > {
281+ type Error = UnicodeError ;
282+
283+ fn try_from ( source : & ' a PathBuf ) -> Result < Self , Self :: Error > {
284+ source. as_os_str ( ) . try_into ( )
285+ }
222286 }
223287}
0 commit comments