Ran 'cargo fmt' to adjust the files.
Just trying to get closer to my preferred coding style.
This commit is contained in:
parent
fe7537f238
commit
3a0684c33e
@ -19,7 +19,7 @@ pub struct DirMonitor
|
||||
dir: PathBuf,
|
||||
|
||||
/// The files that are being monitored within the directory.
|
||||
monitored_files: MonitoredFiles,
|
||||
monitored_files: MonitoredFiles
|
||||
}
|
||||
|
||||
|
||||
@ -31,11 +31,8 @@ impl DirMonitor
|
||||
/// monitor_path: A string representation of directory to monitor.
|
||||
pub fn new(monitor_path: &str) -> Self
|
||||
{
|
||||
DirMonitor
|
||||
{
|
||||
dir: PathBuf::from(monitor_path),
|
||||
monitored_files: MonitoredFiles::new()
|
||||
}
|
||||
DirMonitor { dir: PathBuf::from(monitor_path),
|
||||
monitored_files: MonitoredFiles::new() }
|
||||
}
|
||||
|
||||
/// Scan the monitored directory and all of its sub directories and monitors
|
||||
@ -48,8 +45,7 @@ impl DirMonitor
|
||||
match scan_dir(&self.dir, &mut self.monitored_files, &self.dir)
|
||||
{
|
||||
Ok(_) =>
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
@ -69,30 +65,34 @@ impl DirMonitor
|
||||
println!("{}", self.monitored_files);
|
||||
}
|
||||
|
||||
/// Start monitoring the directory asyncronously and process changes within the directory
|
||||
/// until a termination message is received.
|
||||
pub async fn monitor(&mut self, mut term_receiver: tokio::sync::watch::Receiver<bool>)
|
||||
/// Start monitoring the directory asyncronously and process changes within
|
||||
/// the directory until a termination message is received.
|
||||
pub async fn monitor(&mut self,
|
||||
mut term_receiver: tokio::sync::watch::Receiver<bool>)
|
||||
{
|
||||
let mut running: bool = true;
|
||||
|
||||
// Setup the notify crate to watch the INBOX directory.
|
||||
let tokio_runtime = tokio::runtime::Handle::current();
|
||||
let (notify_sender, mut notify_receiver) = tokio::sync::mpsc::channel::<Event>(10);
|
||||
let (notify_sender, mut notify_receiver) =
|
||||
tokio::sync::mpsc::channel::<Event>(10);
|
||||
let wrapped_sender = NotifySender::new(tokio_runtime, notify_sender);
|
||||
let mut fs_watcher: RecommendedWatcher =
|
||||
match notify::recommended_watcher(wrapped_sender)
|
||||
{
|
||||
Ok(watcher) => { watcher }
|
||||
Ok(watcher) => watcher,
|
||||
Err(e) =>
|
||||
{
|
||||
// Just panic because we cannot watch the directories so the program
|
||||
// would be useless and this saves from having to press CTRL-C.
|
||||
// Just panic because we cannot watch the directories so the
|
||||
// program would be useless and this saves from
|
||||
// having to press CTRL-C.
|
||||
eprintln!("Unable to create watcher: {}", e);
|
||||
panic!();
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = fs_watcher.watch(&self.dir, notify::RecursiveMode::Recursive)
|
||||
if let Err(e) =
|
||||
fs_watcher.watch(&self.dir, notify::RecursiveMode::Recursive)
|
||||
{
|
||||
// Just panic because we cannot watch the directories so the program
|
||||
// would be useless and this saves from having to press CTRL-C.
|
||||
@ -107,8 +107,7 @@ impl DirMonitor
|
||||
// We are listening for messages from either the notify receiver or
|
||||
// the termination receiver. When ever one of them comes across we
|
||||
// will process it.
|
||||
tokio::select!
|
||||
{
|
||||
tokio::select! {
|
||||
// Handle listening for the notify watcher events.
|
||||
// These are the changes that we care about from the file system.
|
||||
Some(mut event) = notify_receiver.recv() =>
|
||||
@ -132,9 +131,10 @@ impl DirMonitor
|
||||
|
||||
|
||||
|
||||
/// Scans a directory, and all of its sub directories, and creates a list of the files
|
||||
/// inside and their last modification time.
|
||||
fn scan_dir(base_dir: &Path, monitored_files: &mut MonitoredFiles, dir: &Path) -> std::io::Result<()>
|
||||
/// Scans a directory, and all of its sub directories, and creates a list of the
|
||||
/// files inside and their last modification time.
|
||||
fn scan_dir(base_dir: &Path, monitored_files: &mut MonitoredFiles, dir: &Path)
|
||||
-> std::io::Result<()>
|
||||
{
|
||||
let mut dir_list: Vec<PathBuf> = Vec::new();
|
||||
|
||||
@ -150,7 +150,8 @@ fn scan_dir(base_dir: &Path, monitored_files: &mut MonitoredFiles, dir: &Path) -
|
||||
// Files will be added to the list of monitored files and their
|
||||
// last modification time will be stored.
|
||||
//
|
||||
// TODO: Handle symlinks. Symlinks can be either a file or another directory.
|
||||
// TODO: Handle symlinks. Symlinks can be either a file or another
|
||||
// directory.
|
||||
if meta.is_dir()
|
||||
{
|
||||
dir_list.push(file.path().clone());
|
||||
@ -159,7 +160,8 @@ fn scan_dir(base_dir: &Path, monitored_files: &mut MonitoredFiles, dir: &Path) -
|
||||
{
|
||||
let last_mod_time: std::time::SystemTime = meta.modified()?;
|
||||
|
||||
monitored_files.add(&strip_path_prefix(&file.path(), base_dir), last_mod_time);
|
||||
monitored_files.add(&strip_path_prefix(&file.path(), base_dir),
|
||||
last_mod_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,9 @@ impl Event
|
||||
{
|
||||
*path = strip_path_prefix(&path, base_dir);
|
||||
}
|
||||
Event::Rename { from, to, mod_time: _ } =>
|
||||
Event::Rename { from,
|
||||
to,
|
||||
mod_time: _ } =>
|
||||
{
|
||||
*from = strip_path_prefix(&from, base_dir);
|
||||
*to = strip_path_prefix(&to, base_dir);
|
||||
@ -96,7 +98,9 @@ impl std::fmt::Display for Event
|
||||
{
|
||||
write!(f, "[MOD] {}", path.display())
|
||||
}
|
||||
Event::Rename { from, to, mod_time: _ } =>
|
||||
Event::Rename { from,
|
||||
to,
|
||||
mod_time: _ } =>
|
||||
{
|
||||
writeln!(f, "[DEL] {}", from.display())?;
|
||||
write!(f, "[NEW] {}", to.display())
|
||||
|
20
src/main.rs
20
src/main.rs
@ -11,7 +11,6 @@ mod util;
|
||||
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use tokio::sync::watch;
|
||||
|
||||
use crate::dir_monitor::DirMonitor;
|
||||
@ -48,10 +47,7 @@ fn create_directory(dir: &str) -> Option<String>
|
||||
|
||||
match std::fs::create_dir_all(inbox_dir.clone())
|
||||
{
|
||||
Ok(_) =>
|
||||
{
|
||||
Some(inbox_dir)
|
||||
}
|
||||
Ok(_) => Some(inbox_dir),
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
@ -99,8 +95,7 @@ async fn main()
|
||||
directory_monitor.print_monitored_files();
|
||||
|
||||
// Run our directory monitor.
|
||||
let mon_task = tokio::spawn(async move
|
||||
{
|
||||
let mon_task = tokio::spawn(async move {
|
||||
// Program workflow step 2 (terminated by step 3).
|
||||
// This can be done async because we are waiting on
|
||||
// events to be loaded from the notify library and
|
||||
@ -122,8 +117,7 @@ async fn main()
|
||||
|
||||
// Run until Ctrl-C is pressed.
|
||||
// Once it is pressed it will send a message to stop.
|
||||
let _term_task = tokio::spawn(async move
|
||||
{
|
||||
let _term_task = tokio::spawn(async move {
|
||||
// Program workflow step 3.
|
||||
// Async with message passing so it can run and listen
|
||||
// for the termination signal. It uses a watch channel
|
||||
@ -136,8 +130,12 @@ async fn main()
|
||||
// finish once the termination task has finished.
|
||||
match mon_task.await
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(e) => { eprintln!("Error during monitoring task: {}", e); }
|
||||
Ok(_) =>
|
||||
{}
|
||||
Err(e) =>
|
||||
{
|
||||
eprintln!("Error during monitoring task: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use chrono::{DateTime, Local};
|
||||
@ -22,10 +22,7 @@ impl MonitoredFiles
|
||||
/// Create a new empty set of monitored files.
|
||||
pub fn new() -> Self
|
||||
{
|
||||
MonitoredFiles
|
||||
{
|
||||
files: HashMap::new()
|
||||
}
|
||||
MonitoredFiles { files: HashMap::new() }
|
||||
}
|
||||
|
||||
/// Process an event and change the monitored files.
|
||||
@ -90,11 +87,17 @@ impl std::fmt::Display for MonitoredFiles
|
||||
|
||||
if !it.peek().is_none()
|
||||
{
|
||||
writeln!(f, "[{}] {}", date_time.format("%m/%d/%Y %H:%M"), path.display())?;
|
||||
writeln!(f,
|
||||
"[{}] {}",
|
||||
date_time.format("%m/%d/%Y %H:%M"),
|
||||
path.display())?;
|
||||
}
|
||||
else
|
||||
{
|
||||
write!(f, "[{}] {}", date_time.format("%m/%d/%Y %H:%M"), path.display())?;
|
||||
write!(f,
|
||||
"[{}] {}",
|
||||
date_time.format("%m/%d/%Y %H:%M"),
|
||||
path.display())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,8 @@ impl NotifySender
|
||||
sender: tokio::sync::mpsc::Sender<crate::event::Event>)
|
||||
-> Self
|
||||
{
|
||||
NotifySender
|
||||
{
|
||||
tokio_runtime,
|
||||
sender
|
||||
}
|
||||
NotifySender { tokio_runtime,
|
||||
sender }
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,9 +47,9 @@ impl notify::EventHandler for NotifySender
|
||||
{
|
||||
let notify_sender = self.sender.clone();
|
||||
|
||||
self.tokio_runtime.spawn(async move
|
||||
{
|
||||
if let Err(e) = notify_sender.send(monitor_event).await
|
||||
self.tokio_runtime.spawn(async move {
|
||||
if let Err(e) =
|
||||
notify_sender.send(monitor_event).await
|
||||
{
|
||||
eprintln!("Notify EventHandler: {}", e);
|
||||
}
|
||||
@ -88,21 +85,19 @@ fn process_notify_event(event: notify::Event) -> Option<crate::event::Event>
|
||||
process_remove_event(kind, event.paths)
|
||||
}
|
||||
|
||||
_ => { None }
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Process the Create event into a New event.
|
||||
fn process_create_event(event: notify::event::CreateKind,
|
||||
paths: Vec<PathBuf>)
|
||||
fn process_create_event(event: notify::event::CreateKind, paths: Vec<PathBuf>)
|
||||
-> Option<crate::event::Event>
|
||||
{
|
||||
if event == notify::event::CreateKind::File
|
||||
{
|
||||
let mod_time: std::time::SystemTime =
|
||||
match get_file_mod_time(&paths[0])
|
||||
let mod_time: std::time::SystemTime = match get_file_mod_time(&paths[0])
|
||||
{
|
||||
Ok(time) => { time }
|
||||
Ok(time) => time,
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
@ -112,33 +107,31 @@ fn process_create_event(event: notify::event::CreateKind,
|
||||
}
|
||||
};
|
||||
|
||||
return Some(crate::event::Event::New
|
||||
{
|
||||
path: paths[0].clone(),
|
||||
mod_time: mod_time
|
||||
});
|
||||
return Some(crate::event::Event::New { path: paths[0].clone(),
|
||||
mod_time: mod_time });
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Process the modify event into either a Modify event or a Rename event.
|
||||
fn process_modify_event(event: notify::event::ModifyKind,
|
||||
paths: Vec<PathBuf>)
|
||||
fn process_modify_event(event: notify::event::ModifyKind, paths: Vec<PathBuf>)
|
||||
-> Option<crate::event::Event>
|
||||
{
|
||||
match event
|
||||
{
|
||||
// This is just handling the events. On my system they came across as Any for
|
||||
// the MetadataKind, but the documentation seemed to hint that modification
|
||||
// times should be on write events. So for the sake of being done without testing
|
||||
// this on different platforms the Any modification event will trigger a time lookup.
|
||||
notify::event::ModifyKind::Any | notify::event::ModifyKind::Metadata(_) =>
|
||||
// This is just handling the events. On my system they came across as Any
|
||||
// for the MetadataKind, but the documentation seemed to hint that
|
||||
// modification times should be on write events. So for the sake of
|
||||
// being done without testing this on different platforms the Any
|
||||
// modification event will trigger a time lookup.
|
||||
notify::event::ModifyKind::Any |
|
||||
notify::event::ModifyKind::Metadata(_) =>
|
||||
{
|
||||
let mod_time: std::time::SystemTime =
|
||||
match get_file_mod_time(&paths[0])
|
||||
let mod_time: std::time::SystemTime = match get_file_mod_time(&paths
|
||||
[0])
|
||||
{
|
||||
Ok(time) => { time }
|
||||
Ok(time) => time,
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
@ -148,11 +141,8 @@ fn process_modify_event(event: notify::event::ModifyKind,
|
||||
}
|
||||
};
|
||||
|
||||
Some(crate::event::Event::Modify
|
||||
{
|
||||
path: paths[0].clone(),
|
||||
mod_time: mod_time
|
||||
})
|
||||
Some(crate::event::Event::Modify { path: paths[0].clone(),
|
||||
mod_time: mod_time })
|
||||
}
|
||||
|
||||
// Handling a rename event so that during testing when a file is
|
||||
@ -168,32 +158,27 @@ fn process_modify_event(event: notify::event::ModifyKind,
|
||||
let mod_time: std::time::SystemTime =
|
||||
match get_file_mod_time(&paths[1])
|
||||
{
|
||||
Ok(time) => { time }
|
||||
Ok(time) => time,
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
eprintln!("Unable to open file to retrieve modification time: {}",
|
||||
eprintln!("Unable to open file to retrieve \
|
||||
modification time: {}",
|
||||
e);
|
||||
std::time::SystemTime::now()
|
||||
}
|
||||
};
|
||||
|
||||
Some(crate::event::Event::Rename
|
||||
{
|
||||
from: paths[0].clone(),
|
||||
Some(crate::event::Event::Rename { from: paths[0].clone(),
|
||||
to: paths[1].clone(),
|
||||
mod_time: mod_time
|
||||
})
|
||||
mod_time: mod_time })
|
||||
}
|
||||
|
||||
// This is for when a file is renamed and only the from
|
||||
// file is in the monitored directories.
|
||||
notify::event::RenameMode::From =>
|
||||
{
|
||||
Some(crate::event::Event::Delete
|
||||
{
|
||||
path: paths[0].clone(),
|
||||
})
|
||||
Some(crate::event::Event::Delete { path: paths[0].clone() })
|
||||
}
|
||||
|
||||
// This is for when a file is renamed and both the to file
|
||||
@ -203,42 +188,36 @@ fn process_modify_event(event: notify::event::ModifyKind,
|
||||
let mod_time: std::time::SystemTime =
|
||||
match get_file_mod_time(&paths[0])
|
||||
{
|
||||
Ok(time) => { time }
|
||||
Ok(time) => time,
|
||||
|
||||
Err(e) =>
|
||||
{
|
||||
eprintln!("Unable to open file to retrieve modification time: {}",
|
||||
eprintln!("Unable to open file to retrieve \
|
||||
modification time: {}",
|
||||
e);
|
||||
std::time::SystemTime::now()
|
||||
}
|
||||
};
|
||||
|
||||
Some(crate::event::Event::New
|
||||
{
|
||||
path: paths[0].clone(),
|
||||
mod_time: mod_time
|
||||
})
|
||||
Some(crate::event::Event::New { path: paths[0].clone(),
|
||||
mod_time: mod_time })
|
||||
}
|
||||
|
||||
_ => { None }
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
_ => { None }
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Process the remove event into a Delete event.
|
||||
fn process_remove_event(event: notify::event::RemoveKind,
|
||||
paths: Vec<PathBuf>)
|
||||
fn process_remove_event(event: notify::event::RemoveKind, paths: Vec<PathBuf>)
|
||||
-> Option<crate::event::Event>
|
||||
{
|
||||
if event == notify::event::RemoveKind::File
|
||||
{
|
||||
return Some(crate::event::Event::Delete
|
||||
{
|
||||
path: paths[0].clone(),
|
||||
});
|
||||
return Some(crate::event::Event::Delete { path: paths[0].clone() });
|
||||
}
|
||||
|
||||
None
|
||||
|
14
src/util.rs
14
src/util.rs
@ -2,7 +2,8 @@
|
||||
///
|
||||
/// If it is unable to get the modification time from the file system
|
||||
/// it will default to the current system time.
|
||||
pub fn get_file_mod_time(path: &std::path::Path) -> std::io::Result<std::time::SystemTime>
|
||||
pub fn get_file_mod_time(path: &std::path::Path)
|
||||
-> std::io::Result<std::time::SystemTime>
|
||||
{
|
||||
let file = std::fs::File::open(path)?;
|
||||
let meta = file.metadata()?;
|
||||
@ -15,8 +16,10 @@ pub fn get_file_mod_time(path: &std::path::Path) -> std::io::Result<std::time::S
|
||||
Ok(std::time::SystemTime::now())
|
||||
}
|
||||
|
||||
/// Create a new PathBuf that is the same as path but has the base removed if it can.
|
||||
pub fn strip_path_prefix(path: &std::path::Path, base: &std::path::Path) -> std::path::PathBuf
|
||||
/// Create a new PathBuf that is the same as path but has the base removed if it
|
||||
/// can.
|
||||
pub fn strip_path_prefix(path: &std::path::Path, base: &std::path::Path)
|
||||
-> std::path::PathBuf
|
||||
{
|
||||
match &path.strip_prefix(base)
|
||||
{
|
||||
@ -28,9 +31,6 @@ pub fn strip_path_prefix(path: &std::path::Path, base: &std::path::Path) -> std:
|
||||
final_path
|
||||
}
|
||||
|
||||
Err(_) =>
|
||||
{
|
||||
std::path::PathBuf::from(path)
|
||||
}
|
||||
Err(_) => std::path::PathBuf::from(path)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user