Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
- introduce function to create a wide path
- remove redundant `is_dir` field, but provide utilities to figure out if it is a directory or not.
  • Loading branch information
Byron committed Jan 10, 2024
1 parent 63639c3 commit 8dad3df
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/freedesktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ pub fn metadata(item: &TrashItem) -> Result<TrashItemMetadata, Error> {
} else {
TrashItemSize::Bytes(metadata.len())
};
Ok(TrashItemMetadata { is_dir, size })
Ok(TrashItemMetadata { size })
}

/// The path points to:
Expand Down
26 changes: 21 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,20 +305,36 @@ impl Hash for TrashItem {
}

/// Size of a [`TrashItem`] in bytes or entries
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum TrashItemSize {
/// Number of bytes in a file
Bytes(u64),
/// Number of entries in a directory, non-recursive
Entries(usize),
}

impl TrashItemSize {
/// The size of a file in bytes, if this item is a file.
pub fn size(&self) -> Option<u64> {
match self {
TrashItemSize::Bytes(s) => Some(*s),
TrashItemSize::Entries(_) => None,
}
}

/// The amount of entries in the directory, if this is a directory.
pub fn entries(&self) -> Option<usize> {
match self {
TrashItemSize::Bytes(_) => None,
TrashItemSize::Entries(e) => Some(*e),
}
}
}

/// Metadata about a [`TrashItem`]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct TrashItemMetadata {
/// True if the [`TrashItem`] is a directory, false if it is a file
pub is_dir: bool,
/// The size of the item, as a [`TrashItemSize`] enum
/// The size of the item, depending on whether or not it is a directory.
pub size: TrashItemSize,
}

Expand Down
21 changes: 11 additions & 10 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ impl From<windows::core::Error> for Error {
}
}

fn to_wide_path(path: impl AsRef<OsStr>) -> Vec<u16> {
path.as_ref().encode_wide().chain(std::iter::once(0)).collect()
}

#[derive(Clone, Default, Debug)]
pub struct PlatformTrashContext;
impl PlatformTrashContext {
Expand All @@ -56,8 +60,7 @@ impl TrashContext {

for full_path in full_paths.iter() {
let path_prefix = ['\\' as u16, '\\' as u16, '?' as u16, '\\' as u16];
let wide_path_container: Vec<_> =
full_path.as_os_str().encode_wide().chain(std::iter::once(0)).collect();
let wide_path_container = to_wide_path(full_path);
let wide_path_slice = if wide_path_container.starts_with(&path_prefix) {
&wide_path_container[path_prefix.len()..]
} else {
Expand Down Expand Up @@ -129,7 +132,7 @@ pub fn list() -> Result<Vec<TrashItem>, Error> {

pub fn metadata(item: &TrashItem) -> Result<TrashItemMetadata, Error> {
ensure_com_initialized();
let id_as_wide: Vec<u16> = item.id.encode_wide().chain(std::iter::once(0)).collect();
let id_as_wide = to_wide_path(&item.id);
let parsing_name = PCWSTR(id_as_wide.as_ptr());
let item: IShellItem = unsafe { SHCreateItemFromParsingName(parsing_name, None)? };
let is_dir = unsafe { item.GetAttributes(SFGAO_FOLDER)? } == SFGAO_FOLDER;
Expand Down Expand Up @@ -159,7 +162,7 @@ pub fn metadata(item: &TrashItem) -> Result<TrashItemMetadata, Error> {
let item2: IShellItem2 = item.cast()?;
TrashItemSize::Bytes(unsafe { item2.GetUInt64(&PKEY_Size)? })
};
Ok(TrashItemMetadata { is_dir, size })
Ok(TrashItemMetadata { size })
}

pub fn purge_all<I>(items: I) -> Result<(), Error>
Expand All @@ -174,7 +177,7 @@ where
let mut at_least_one = false;
for item in items {
at_least_one = true;
let id_as_wide: Vec<u16> = item.borrow().id.encode_wide().chain(std::iter::once(0)).collect();
let id_as_wide = to_wide_path(&item.borrow().id);
let parsing_name = PCWSTR(id_as_wide.as_ptr());
let trash_item: IShellItem = SHCreateItemFromParsingName(parsing_name, None)?;
pfo.DeleteItem(&trash_item, None)?;
Expand Down Expand Up @@ -210,14 +213,12 @@ where
let pfo: IFileOperation = CoCreateInstance(&FileOperation as *const _, None, CLSCTX_ALL)?;
pfo.SetOperationFlags(FOF_NO_UI | FOFX_EARLYFAILURE)?;
for item in items.iter() {
let id_as_wide: Vec<u16> = item.id.encode_wide().chain(std::iter::once(0)).collect();
let id_as_wide = to_wide_path(&item.id);
let parsing_name = PCWSTR(id_as_wide.as_ptr());
let trash_item: IShellItem = SHCreateItemFromParsingName(parsing_name, None)?;
let parent_path_wide: Vec<_> =
item.original_parent.as_os_str().encode_wide().chain(std::iter::once(0)).collect();
let parent_path_wide = to_wide_path(&item.original_parent);
let orig_folder_shi: IShellItem = SHCreateItemFromParsingName(PCWSTR(parent_path_wide.as_ptr()), None)?;
let name_wstr: Vec<_> =
AsRef::<OsStr>::as_ref(&item.name).encode_wide().chain(std::iter::once(0)).collect();
let name_wstr = to_wide_path(&item.name);

pfo.MoveItem(&trash_item, &orig_folder_shi, PCWSTR(name_wstr.as_ptr()), None)?;
}
Expand Down

0 comments on commit 8dad3df

Please sign in to comment.