Skip to content

Commit

Permalink
Add metadata function, implement for freedesktop
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed Jan 6, 2024
1 parent 916d769 commit 3bea3e2
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
20 changes: 20 additions & 0 deletions examples/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#[cfg(not(any(
target_os = "windows",
all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android"))
)))]
fn main() {
println!("This is currently only supported on Windows, Linux, and other Freedesktop.org compliant OSes");
}

#[cfg(any(
target_os = "windows",
all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android"))
))]
fn main() {
let trash_items = trash::os_limited::list().unwrap();

for item in trash_items {
let metadata = trash::os_limited::metadata(&item).unwrap();
println!("{:?}: {:?}", item, metadata);
}
}
21 changes: 19 additions & 2 deletions src/freedesktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
use std::{
borrow::Borrow,
collections::HashSet,
fs::{File, OpenOptions},
fs::{self, File, OpenOptions},
io::{BufRead, BufReader, Write},
os::unix::fs::PermissionsExt,
path::{Path, PathBuf},
};

use log::{debug, warn};

use crate::{Error, TrashContext, TrashItem};
use crate::{Error, TrashContext, TrashItem, TrashItemMetadata};

type FsError = (PathBuf, std::io::Error);

Expand Down Expand Up @@ -218,6 +218,23 @@ pub fn list() -> Result<Vec<TrashItem>, Error> {
Ok(result)
}

pub fn metadata(item: &TrashItem) -> Result<TrashItemMetadata, Error> {
// 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;

// 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
// the specification.
let file = restorable_file_in_trash_from_info_file(info_file);
assert!(virtually_exists(&file).map_err(|e| fs_error(&file, e))?);
let metadata = fs::symlink_metadata(&file).map_err(|e| fs_error(&file, e))?;
let is_dir = metadata.is_dir();
let size =
if is_dir { fs::read_dir(&file).map_err(|e| fs_error(&file, e))?.count() as u64 } else { metadata.len() };
Ok(TrashItemMetadata { is_dir, size })
}

/// The path points to:
/// - existing file | directory | symlink => Ok(true)
/// - broken symlink => Ok(true)
Expand Down
26 changes: 25 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@ impl Hash for TrashItem {
}
}

/// Metadata about a [`TrashItem`]
#[derive(Debug, Clone)]
pub struct TrashItemMetadata {
/// True if the [`TrashItem`] is a directory, false if it is a file
pub is_dir: bool,
/// Number of entries for directories, number of bytes for files
pub size: u64,
}

#[cfg(any(
target_os = "windows",
all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android"))
Expand All @@ -318,7 +327,7 @@ pub mod os_limited {
hash::{Hash, Hasher},
};

use super::{platform, Error, TrashItem};
use super::{platform, Error, TrashItem, TrashItemMetadata};

/// Returns all [`TrashItem`]s that are currently in the trash.
///
Expand All @@ -335,6 +344,21 @@ pub mod os_limited {
platform::list()
}

/// Returns the [`TrashItemMetadata`] for a [`TrashItem`]
///
/// # Example
///
/// ```
/// use trash::os_limited::{list, metadata};
/// let trash_items = list().unwrap();
/// for item in trash_items {
/// println!("{:#?}", metadata(&item).unwrap());
/// }
/// ```
pub fn metadata(item: &TrashItem) -> Result<TrashItemMetadata, Error> {
platform::metadata(item)
}

/// Deletes all the provided [`TrashItem`]s permanently.
///
/// This function consumes the provided items.
Expand Down

0 comments on commit 3bea3e2

Please sign in to comment.