diff --git a/src/freedesktop.rs b/src/freedesktop.rs index 02fdcb9..53c79d7 100644 --- a/src/freedesktop.rs +++ b/src/freedesktop.rs @@ -232,7 +232,7 @@ pub fn metadata(item: &TrashItem) -> Result { } else { TrashItemSize::Bytes(metadata.len()) }; - Ok(TrashItemMetadata { is_dir, size }) + Ok(TrashItemMetadata { size }) } /// The path points to: diff --git a/src/lib.rs b/src/lib.rs index 2a36df7..a039985 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -305,7 +305,7 @@ 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), @@ -313,12 +313,28 @@ pub enum TrashItemSize { Entries(usize), } +impl TrashItemSize { + /// The size of a file in bytes, if this item is a file. + pub fn size(&self) -> Option { + 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 { + 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, } diff --git a/src/windows.rs b/src/windows.rs index cbe1c1c..12c1a82 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -38,6 +38,10 @@ impl From for Error { } } +fn to_wide_path(path: impl AsRef) -> Vec { + path.as_ref().encode_wide().chain(std::iter::once(0)).collect() +} + #[derive(Clone, Default, Debug)] pub struct PlatformTrashContext; impl PlatformTrashContext { @@ -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 { @@ -129,7 +132,7 @@ pub fn list() -> Result, Error> { pub fn metadata(item: &TrashItem) -> Result { ensure_com_initialized(); - let id_as_wide: Vec = 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; @@ -159,7 +162,7 @@ pub fn metadata(item: &TrashItem) -> Result { let item2: IShellItem2 = item.cast()?; TrashItemSize::Bytes(unsafe { item2.GetUInt64(&PKEY_Size)? }) }; - Ok(TrashItemMetadata { is_dir, size }) + Ok(TrashItemMetadata { size }) } pub fn purge_all(items: I) -> Result<(), Error> @@ -174,7 +177,7 @@ where let mut at_least_one = false; for item in items { at_least_one = true; - let id_as_wide: Vec = 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)?; @@ -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 = 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::::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)?; }