From ebfb38ebb2dff3dcb353b9d8cd01d41d9abf486e Mon Sep 17 00:00:00 2001
From: Ben Bridle <ben@derelict.engineering>
Date: Tue, 30 Jul 2024 18:30:46 +1200
Subject: Update file device to compile on Windows

Construction of OsStrings is handled differently between Windows and
Unix, using platform-specific APIs.

The method OsStr::as_bytes was also changed to OsStr::as_encoded_bytes
at some point between Rust versions 1.69 and 1.80.
---
 src/devices/file.rs | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

(limited to 'src/devices/file.rs')

diff --git a/src/devices/file.rs b/src/devices/file.rs
index e8db41a..fc1b56c 100644
--- a/src/devices/file.rs
+++ b/src/devices/file.rs
@@ -13,13 +13,25 @@ pub use entry::*;
 use operations::*;
 
 use std::fs::{OpenOptions, metadata};
-use std::os::unix::ffi::OsStrExt;
 use std::path::{Component, Path, PathBuf};
 
 fn is_blank_path(path: &Path) -> bool {
     path == PathBuf::new()
 }
 
+fn bytes_to_path(bytes: &[u8]) -> PathBuf {
+    #[cfg(target_family = "unix")]
+    let os_string: std::ffi::OsString = {
+        std::os::unix::ffi::OsStringExt::from_vec(Vec::from(bytes))
+    };
+    #[cfg(target_family = "windows")]
+    let os_string: std::ffi::OsString = {
+        let wide: Vec<u16> = bytes.iter().map(|b| *b as u16).collect();
+        std::os::windows::ffi::OsStringExt::from_wide(&wide)
+    };
+    os_string.into()
+}
+
 pub struct FileDevice {
     /// The path to which the file device is confined. Files and directories
     /// outside of this directory cannot be accessed.
@@ -117,7 +129,7 @@ impl FileDevice {
                 let file_entry = Entry::File(BufferedFile::new(file));
                 self.entry = Some((file_entry, path.to_owned()));
                 let relative = remove_base(&path, &self.base_path).unwrap();
-                self.name_buffer.populate(relative.as_os_str().as_bytes());
+                self.name_buffer.populate(relative.as_os_str().as_encoded_bytes());
                 return Ok(());
             };
         } else if metadata.is_dir() {
@@ -125,7 +137,7 @@ impl FileDevice {
                 let dir_entry = Entry::Directory(listing);
                 self.entry = Some((dir_entry, path.to_owned()));
                 let relative = remove_base(&path, &self.base_path).unwrap();
-                self.name_buffer.populate(relative.as_os_str().as_bytes());
+                self.name_buffer.populate(relative.as_os_str().as_encoded_bytes());
                 return Ok(());
             };
         };
-- 
cgit v1.2.3-70-g09d2