| Crates.io | gravityfile-ops |
| lib.rs | gravityfile-ops |
| version | 0.2.2 |
| created_at | 2025-12-17 22:53:54.778506+00 |
| updated_at | 2026-01-16 13:09:33.920053+00 |
| description | File operations engine for gravityfile |
| homepage | |
| repository | https://github.com/epistates/gravityfile |
| max_upload_size | |
| id | 1991253 |
| size | 99,315 |
Async file operations engine for gravityfile with progress reporting and undo support.
This crate provides the file operations layer (copy, move, rename, create, delete) with conflict handling, progress updates via channels, and an undo log.
trash crate for recoverable deletionsuse gravityfile_ops::{start_copy, CopyOptions, CopyResult};
use std::path::PathBuf;
let sources = vec![PathBuf::from("/path/to/file.txt")];
let destination = PathBuf::from("/path/to/destination");
let options = CopyOptions::default();
let mut rx = start_copy(sources, destination, options);
while let Some(result) = rx.recv().await {
match result {
CopyResult::Progress(progress) => {
println!("{:.1}% complete", progress.percentage());
}
CopyResult::Conflict(conflict) => {
println!("Conflict: {} at {}", conflict.kind, conflict.destination.display());
}
CopyResult::Complete(complete) => {
println!("{}", complete.summary());
}
}
}
use gravityfile_ops::{start_move, MoveOptions, MoveResult};
use std::path::PathBuf;
let sources = vec![PathBuf::from("/path/to/file.txt")];
let destination = PathBuf::from("/path/to/destination");
let options = MoveOptions::default();
let mut rx = start_move(sources, destination, options);
while let Some(result) = rx.recv().await {
match result {
MoveResult::Progress(progress) => {
println!("Moving: {:?}", progress.current_file);
}
MoveResult::Complete(complete) => {
println!("{}", complete.summary());
}
_ => {}
}
}
use gravityfile_ops::{start_rename, RenameResult};
use std::path::PathBuf;
let source = PathBuf::from("/path/to/old_name.txt");
let new_name = "new_name.txt";
let mut rx = start_rename(source, new_name.to_string());
while let Some(result) = rx.recv().await {
match result {
RenameResult::Complete(complete) => {
if complete.is_success() {
println!("Renamed successfully");
}
}
_ => {}
}
}
use gravityfile_ops::{start_create_file, start_create_directory, CreateResult};
use std::path::PathBuf;
// Create a file
let mut rx = start_create_file(PathBuf::from("/path/to/new_file.txt"));
while let Some(CreateResult::Complete(c)) = rx.recv().await {
println!("{}", c.summary());
}
// Create a directory
let mut rx = start_create_directory(PathBuf::from("/path/to/new_dir"));
while let Some(CreateResult::Complete(c)) = rx.recv().await {
println!("{}", c.summary());
}
use gravityfile_ops::{UndoLog, UndoableOperation, execute_undo};
use std::path::PathBuf;
let mut undo_log = UndoLog::new(100); // Keep last 100 operations
// Record operations as they happen
undo_log.record_create_file(PathBuf::from("/path/to/file.txt"));
undo_log.record_rename(
PathBuf::from("/path/to/new.txt"),
"old.txt".to_string(),
"new.txt".to_string(),
);
// Undo the most recent operation
if let Some(entry) = undo_log.pop() {
let result = execute_undo(&entry.operation).await?;
println!("Undone: {}", entry.description);
}
Represents an operation to be executed:
pub enum FileOperation {
Copy { sources: Vec<PathBuf>, destination: PathBuf },
Move { sources: Vec<PathBuf>, destination: PathBuf },
Rename { source: PathBuf, new_name: String },
Delete { targets: Vec<PathBuf>, use_trash: bool },
CreateFile { path: PathBuf },
CreateDirectory { path: PathBuf },
}
How to handle conflicts during operations:
pub enum ConflictResolution {
Skip, // Skip this item
Overwrite, // Replace existing
AutoRename, // Rename to "file (1).txt"
SkipAll, // Skip all remaining conflicts
OverwriteAll, // Overwrite all remaining conflicts
Abort, // Cancel the operation
}
Progress information for ongoing operations:
pub struct OperationProgress {
pub operation_type: OperationType,
pub files_completed: usize,
pub files_total: usize,
pub bytes_processed: u64,
pub bytes_total: u64,
pub current_file: Option<PathBuf>,
pub errors: Vec<OperationError>,
}
Operations that can be reversed:
pub enum UndoableOperation {
FilesMoved { moves: Vec<(PathBuf, PathBuf)> },
FilesCopied { created: Vec<PathBuf> },
FilesDeleted { trash_entries: Vec<(PathBuf, PathBuf)> },
FileRenamed { path: PathBuf, old_name: String, new_name: String },
FileCreated { path: PathBuf },
DirectoryCreated { path: PathBuf },
}
The crate is organized into focused modules:
FileOperation enum and error typesLicensed under either of Apache License, Version 2.0 or MIT license at your option.