1 // Licensed under the Apache License, Version 2.0 2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. 4 // All files in the project carrying such notice may not be copied, modified, or distributed 5 // except according to those terms. 6 use std::ffi::{OsStr, OsString}; 7 use std::os::windows::ffi::{OsStrExt, OsStringExt}; 8 use std::path::PathBuf; 9 use std::slice::from_raw_parts; 10 11 pub trait ToWide { to_wide(&self) -> Vec<u16>12 fn to_wide(&self) -> Vec<u16>; to_wide_null(&self) -> Vec<u16>13 fn to_wide_null(&self) -> Vec<u16>; 14 } 15 impl<T> ToWide for T where T: AsRef<OsStr> { 16 #[inline] to_wide(&self) -> Vec<u16>17 fn to_wide(&self) -> Vec<u16> { 18 self.as_ref().encode_wide().collect() 19 } 20 #[inline] to_wide_null(&self) -> Vec<u16>21 fn to_wide_null(&self) -> Vec<u16> { 22 self.as_ref().encode_wide().chain(Some(0)).collect() 23 } 24 } 25 pub trait FromWide where Self: Sized { from_wide(wide: &[u16]) -> Self26 fn from_wide(wide: &[u16]) -> Self; 27 #[inline] from_wide_null(wide: &[u16]) -> Self28 fn from_wide_null(wide: &[u16]) -> Self { 29 let len = wide.iter().take_while(|&&c| c != 0).count(); 30 Self::from_wide(&wide[..len]) 31 } 32 #[inline] from_wide_ptr(wide: *const u16, len: usize) -> Self33 unsafe fn from_wide_ptr(wide: *const u16, len: usize) -> Self { 34 assert!(!wide.is_null()); 35 Self::from_wide(from_raw_parts(wide, len)) 36 } 37 #[inline] from_wide_ptr_null(wide: *const u16) -> Self38 unsafe fn from_wide_ptr_null(wide: *const u16) -> Self { 39 assert!(!wide.is_null()); 40 for i in 0.. { 41 if *wide.offset(i) == 0 { 42 return Self::from_wide_ptr(wide, i as usize) 43 } 44 } 45 unreachable!() 46 } 47 } 48 impl FromWide for OsString { 49 #[inline] from_wide(wide: &[u16]) -> OsString50 fn from_wide(wide: &[u16]) -> OsString { 51 OsStringExt::from_wide(wide) 52 } 53 } 54 impl FromWide for PathBuf { 55 #[inline] from_wide(wide: &[u16]) -> PathBuf56 fn from_wide(wide: &[u16]) -> PathBuf { 57 <OsString as OsStringExt>::from_wide(wide).into() 58 } 59 } 60