use anyhow::Result;
use fsmon::filters::{self, PathOptions};
use fsmon::managed::PathEntry;
use fsmon::EventType;
use fsmon::utils::parse_size_filter;
use std::path::PathBuf;
mod add;
mod clean;
mod daemon;
mod init_cd;
mod manage;
mod query;
mod remove;
pub use add::cmd_add;
pub use clean::cmd_clean;
pub use daemon::cmd_daemon;
pub use init_cd::{cmd_cd, cmd_init};
pub use manage::{cmd_list_managed_paths, cmd_managed};
pub use query::cmd_query;
pub use remove::cmd_remove;
pub fn run(command: crate::Commands) -> Result<()> {
use crate::Commands::*;
match command {
Daemon => cmd_daemon().await_(),
Add(args) => cmd_add(args),
Remove { paths } => {
for path in paths {
eprintln!("[Info] Removing {}...", path.display());
cmd_remove(path)?;
}
Ok(())
}
Managed => cmd_managed(),
Query(args) => cmd_query(args).await_(),
Clean(args) => cmd_clean(args).await_(),
Init => cmd_init(),
Cd => cmd_cd(),
ListManagedPaths => cmd_list_managed_paths(),
}
}
trait AsyncPolyfill {
type Output;
fn await_(self) -> Self::Output;
}
impl<T> AsyncPolyfill for T where T: std::future::Future<Output = Result<()>> {
type Output = Result<()>;
fn await_(self) -> Self::Output {
tokio::runtime::Runtime::new().unwrap().block_on(self)
}
}
pub fn parse_path_entries(entries: &[PathEntry]) -> Result<Vec<(PathBuf, PathOptions)>> {
let mut result = Vec::new();
for entry in entries {
let opts = parse_path_options(entry)?;
result.push((entry.path.clone(), opts));
}
Ok(result)
}
pub fn parse_path_options(entry: &PathEntry) -> Result<PathOptions> {
let size_filter = entry.size.as_ref().map(|s| parse_size_filter(s)).transpose()?;
let event_types = entry
.types
.as_ref()
.map(|v| {
v.iter()
.map(|s| s.parse::<EventType>())
.collect::<std::result::Result<Vec<_>, _>>()
})
.transpose()
.map_err(|e: String| anyhow::anyhow!(e))?;
let (exclude_regex, exclude_invert) = filters::build_exclude_regex(entry.exclude.as_deref(), "exclude")?;
let (exclude_cmd_regex, exclude_cmd_invert) = filters::build_exclude_regex(entry.exclude_cmd.as_deref(), "--exclude-cmd")?;
Ok(PathOptions {
size_filter,
event_types,
exclude_regex,
exclude_invert,
exclude_cmd_regex,
exclude_cmd_invert,
recursive: entry.recursive.unwrap_or(false),
})
}