From af819bf661242a3e6c6f54782f36b7ac68ab0294 Mon Sep 17 00:00:00 2001 From: Junkui Zhang <364772080@qq.com> Date: Fri, 13 Sep 2024 04:14:53 +0800 Subject: [PATCH] windows: Implement `fs::trash_file` and `fs::trash_dir` (#17711) https://github.com/user-attachments/assets/43370cee-26a5-4d27-b86f-656127e03b4a Release Notes: - N/A --- Cargo.toml | 1 + crates/fs/src/fs.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 23b17fd291..79f5ce2dcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -483,6 +483,7 @@ version = "0.58" features = [ "implement", "Foundation_Numerics", + "Storage", "System", "System_Threading", "UI_ViewManagement", diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index a463773e7e..0ec5a4c601 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -342,6 +342,24 @@ impl Fs for RealFs { } } + #[cfg(target_os = "windows")] + async fn trash_file(&self, path: &Path, _options: RemoveOptions) -> Result<()> { + use windows::{ + core::HSTRING, + Storage::{StorageDeleteOption, StorageFile}, + }; + // todo(windows) + // When new version of `windows-rs` release, make this operation `async` + let path = path.canonicalize()?.to_string_lossy().to_string(); + let path_str = path.trim_start_matches("\\\\?\\"); + if path_str.is_empty() { + anyhow::bail!("File path is empty!"); + } + let file = StorageFile::GetFileFromPathAsync(&HSTRING::from(path_str))?.get()?; + file.DeleteAsync(StorageDeleteOption::Default)?.get()?; + Ok(()) + } + #[cfg(target_os = "macos")] async fn trash_dir(&self, path: &Path, options: RemoveOptions) -> Result<()> { self.trash_file(path, options).await @@ -352,6 +370,25 @@ impl Fs for RealFs { self.trash_file(path, options).await } + #[cfg(target_os = "windows")] + async fn trash_dir(&self, path: &Path, _options: RemoveOptions) -> Result<()> { + use windows::{ + core::HSTRING, + Storage::{StorageDeleteOption, StorageFolder}, + }; + + let path = path.canonicalize()?.to_string_lossy().to_string(); + let path_str = path.trim_start_matches("\\\\?\\"); + if path_str.is_empty() { + anyhow::bail!("Folder path is empty!"); + } + // todo(windows) + // When new version of `windows-rs` release, make this operation `async` + let folder = StorageFolder::GetFolderFromPathAsync(&HSTRING::from(path_str))?.get()?; + folder.DeleteAsync(StorageDeleteOption::Default)?.get()?; + Ok(()) + } + async fn open_sync(&self, path: &Path) -> Result> { Ok(Box::new(std::fs::File::open(path)?)) }