Skip to content

Commit

Permalink
feat(purge_all): allow passing in items' ownership or reference
Browse files Browse the repository at this point in the history
  • Loading branch information
TD-Sky committed Aug 4, 2023
1 parent 450edc1 commit d06b874
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
6 changes: 4 additions & 2 deletions src/freedesktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//!

use std::{
borrow::Borrow,
collections::HashSet,
fs::{create_dir_all, File, OpenOptions},
io::{BufRead, BufReader, Write},
Expand Down Expand Up @@ -225,12 +226,13 @@ fn virtually_exists(path: &Path) -> std::io::Result<bool> {

pub fn purge_all<I>(items: I) -> Result<(), Error>
where
I: IntoIterator<Item = TrashItem>,
I: IntoIterator,
<I as IntoIterator>::Item: Borrow<TrashItem>,
{
for item in items.into_iter() {
// When purging an item the "in-trash" filename must be parsed from the trashinfo filename
// which is the filename in the `id` field.
let info_file = &item.id;
let info_file = &item.borrow().id;

// A bunch of unwraps here. This is fine because if any of these fail that means
// that either there's a bug in this code or the target system didn't follow
Expand Down
24 changes: 22 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ pub mod os_limited {
//! Linux or other Freedesktop Trash compliant environment.

use std::{
borrow::Borrow,
collections::HashSet,
hash::{Hash, Hasher},
};
Expand Down Expand Up @@ -332,10 +333,13 @@ pub mod os_limited {
///
/// # Example
///
/// Taking items' ownership:
///
/// ```
/// use std::fs::File;
/// use trash::{delete, os_limited::{list, purge_all}};
/// let filename = "trash-purge_all-example";
///
/// let filename = "trash-purge_all-example-ownership";
/// File::create(filename).unwrap();
/// delete(filename).unwrap();
/// // Collect the filtered list just so that we can make sure there's exactly one element.
Expand All @@ -344,9 +348,25 @@ pub mod os_limited {
/// assert_eq!(selected.len(), 1);
/// purge_all(selected).unwrap();
/// ```
///
/// Taking items' reference:
///
/// ```
/// use std::fs::File;
/// use trash::{delete, os_limited::{list, purge_all}};
///
/// let filename = "trash-purge_all-example-reference";
/// File::create(filename).unwrap();
/// delete(filename).unwrap();
/// let mut selected = list().unwrap();
/// selected.retain(|x| x.name == filename);
/// assert_eq!(selected.len(), 1);
/// purge_all(&selected).unwrap();
/// ```
pub fn purge_all<I>(items: I) -> Result<(), Error>
where
I: IntoIterator<Item = TrashItem>,
I: IntoIterator,
<I as IntoIterator>::Item: Borrow<TrashItem>,
{
platform::purge_all(items)

Check failure on line 371 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build (windows-latest, stable)

type mismatch resolving `<I as IntoIterator>::Item == TrashItem`
}
Expand Down
13 changes: 6 additions & 7 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ mod os_limited {

// Let's try to purge all the items we just created but ignore any errors
// as this test should succeed as long as `list` works properly.
let _ = trash::os_limited::purge_all(items.into_iter().map(|(_name, item)| item).flatten());
let _ = trash::os_limited::purge_all(items.iter().flat_map(|(_name, item)| item));
}

#[test]
fn purge_empty() {
init_logging();
trash::os_limited::purge_all(vec![]).unwrap();
trash::os_limited::purge_all::<Vec<trash::TrashItem>>(vec![]).unwrap();
}

#[test]
Expand Down Expand Up @@ -182,8 +182,7 @@ mod os_limited {
trash::os_limited::list().unwrap().into_iter().filter(|x| x.name.starts_with(&file_name_prefix)).collect();
targets.sort_by(|a, b| a.name.cmp(&b.name));
assert_eq!(targets.len(), file_count);
let remaining_count;
match trash::os_limited::restore_all(targets) {
let remaining_count = match trash::os_limited::restore_all(targets) {
Err(trash::Error::RestoreCollision { remaining_items, .. }) => {
let contains = |v: &Vec<trash::TrashItem>, name: &String| {
for curr in v.iter() {
Expand All @@ -197,15 +196,15 @@ mod os_limited {
for path in names.iter().filter(|filename| !contains(&remaining_items, filename)) {
assert!(File::open(path).is_ok());
}
remaining_count = remaining_items.len();
remaining_items.len()
}
_ => {
for path in names.iter() {
std::fs::remove_file(path).ok();
}
panic!("restore_all was expected to return `trash::ErrorKind::RestoreCollision` but did not.");
}
}
};
let remaining = trash::os_limited::list()
.unwrap()
.into_iter()
Expand Down Expand Up @@ -233,7 +232,7 @@ mod os_limited {

let twin_name = &names[1];
File::create(twin_name).unwrap();
trash::delete(&twin_name).unwrap();
trash::delete(twin_name).unwrap();

let mut targets: Vec<_> =
trash::os_limited::list().unwrap().into_iter().filter(|x| x.name.starts_with(&file_name_prefix)).collect();
Expand Down
4 changes: 3 additions & 1 deletion src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{Error, TrashContext, TrashItem};
use std::{
borrow::Borrow,
ffi::{c_void, OsStr, OsString},
fs,
os::windows::{ffi::OsStrExt, prelude::*},
Expand Down Expand Up @@ -126,6 +127,7 @@ pub fn list() -> Result<Vec<TrashItem>, Error> {
pub fn purge_all<I>(items: I) -> Result<(), Error>
where
I: IntoIterator<Item = TrashItem>,
<I as IntoIterator>::Item: Borrow<TrashItem>,
{
ensure_com_initialized();
unsafe {
Expand All @@ -134,7 +136,7 @@ where
let mut at_least_one = false;
for item in items {
at_least_one = true;
let id_as_wide: Vec<u16> = item.id.encode_wide().chain(std::iter::once(0)).collect();
let id_as_wide: Vec<u16> = item.borrow().id.encode_wide().chain(std::iter::once(0)).collect();
let parsing_name = PCWSTR(id_as_wide.as_ptr());
let trash_item: IShellItem = SHCreateItemFromParsingName(parsing_name, None)?;
pfo.DeleteItem(&trash_item, None)?;
Expand Down

0 comments on commit d06b874

Please sign in to comment.