Simple tool for automatic file management

ft: read specs form the file instead of hard-coded value

hauleth.dev b1fc5149 a94d7668

verified
Changed files
+27 -18
examples
src
+13
examples/images-in-downloads.json
···
+
[
+
{
+
"filter": {
+
"type": "all", "filters": [
+
{"type": "content_type", "mime": "image/png"}
+
]
+
},
+
"location": "~/Downloads",
+
"actions": [
+
"trash"
+
]
+
}
+
]
+14 -18
src/main.rs
···
use futures::prelude::*;
use clap::Parser;
+
use std::io::Read;
+
mod filters;
mod job;
mod pattern;
mod actions;
-
const DATA: &str = r#"
-
[
-
{
-
"filter": {
-
"type": "all", "filters": [
-
{"type": "content_type", "bytes": [137, 80, 78, 71]}
-
]
-
},
-
"location": "~/Downloads",
-
"actions": [
-
{"move": "~/test"}
-
]
-
}
-
]"#;
-
#[derive(Debug, Parser)]
struct Args {
spec: Option<std::path::PathBuf>,
/// Run specified commands instead of printing them
-
#[arg(long, short)]
+
#[arg(long = "no-dry-run", short = '!')]
execute: bool,
}
+
impl Args {
+
fn data(&self) -> std::io::Result<Box<dyn Read>> {
+
Ok(match self.spec {
+
Some(ref path) => Box::new(std::fs::File::open(path)?),
+
None => Box::new(std::io::stdin()),
+
})
+
}
+
}
+
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
-
println!("{args:#?}");
+
let reader = args.data()?;
-
let jobs: Vec<job::Job> = serde_json::from_str(DATA).unwrap();
+
let jobs: Vec<job::Job> = serde_json::from_reader(reader)?;
stream::iter(&jobs)
.then(|job| job.actions())