1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
use std::convert::Infallible; use std::error::Error; use std::path::PathBuf; #[cfg(unix)] use libc::c_char; #[cfg(windows)] use libc::wchar_t; use crate::null_ptr_error; use crate::vec::VecMarshaler; use crate::{FromForeign, InputType, ReturnType, Slice, ToForeign}; pub struct PathBufMarshaler; impl InputType for PathBufMarshaler { type Foreign = Slice<u16>; } impl ReturnType for PathBufMarshaler { type Foreign = Slice<u16>; #[inline(always)] fn foreign_default() -> Self::Foreign { Slice::default() } } impl FromForeign<Slice<u16>, PathBuf> for PathBufMarshaler { type Error = Box<dyn Error>; #[inline(always)] unsafe fn from_foreign(wstr: Slice<u16>) -> Result<PathBuf, Self::Error> { if wstr.data.is_null() { return Err(null_ptr_error()); } use std::os::windows::ffi::OsStringExt; let slice: &[u16] = std::slice::from_raw_parts(wstr.data, wstr.len); let osstr = std::ffi::OsString::from_wide(slice); Ok(osstr.into()) } } impl ToForeign<PathBuf, Slice<u16>> for PathBufMarshaler { type Error = Infallible; #[inline(always)] fn to_foreign(input: PathBuf) -> Result<Slice<u16>, Self::Error> { use std::os::windows::ffi::OsStrExt; let vec: Vec<wchar_t> = input .into_os_string() .encode_wide() .chain(Some(0).into_iter()) .collect(); VecMarshaler::to_foreign(vec) } } impl<E> ToForeign<Result<PathBuf, E>, Slice<u16>> for PathBufMarshaler { type Error = E; #[inline(always)] fn to_foreign(input: Result<PathBuf, E>) -> Result<Slice<u16>, Self::Error> { input.and_then(|x| Ok(PathBufMarshaler::to_foreign(x).unwrap())) } }