v2 start
This commit is contained in:
@@ -1,3 +1,105 @@
|
|||||||
|
use clap::Parser;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_yaml;
|
||||||
|
use std::io::{BufRead, Read, Write};
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let _flags = Flags::new().expect("failed to flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
struct Flags {
|
||||||
|
#[arg(short = 'f', long = "path", default_value = "$PTTODO_FILE")]
|
||||||
|
path: String,
|
||||||
|
|
||||||
|
#[arg(short = 'a', long = "add")]
|
||||||
|
add: Option<String>,
|
||||||
|
|
||||||
|
#[arg(short = 'e', long = "edit", default_value = "false")]
|
||||||
|
edit: bool,
|
||||||
|
|
||||||
|
#[arg(short = 'd', long = "dry-run", default_value = "false")]
|
||||||
|
dry_run: bool,
|
||||||
|
|
||||||
|
#[arg(short = 's', long = "add-schedule")]
|
||||||
|
add_schedule: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flags {
|
||||||
|
pub fn new() -> Result<Flags, String> {
|
||||||
|
let mut result = Flags::parse();
|
||||||
|
|
||||||
|
if result.path.get(..1) == Some("$") {
|
||||||
|
result.path = match std::env::var(result.path.get(1..).unwrap()) {
|
||||||
|
Ok(v) => Ok(v),
|
||||||
|
Err(msg) => Err(format!("'{}' unset: {}", result.path, msg)),
|
||||||
|
}?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = result.files()?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn files(&self) -> Result<Vec<String>, String> {
|
||||||
|
Self::files_with(&self.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn files_with(p: &String) -> Result<Vec<String>, String> {
|
||||||
|
let metadata = match std::fs::metadata(p.clone()) {
|
||||||
|
Ok(v) => Ok(v),
|
||||||
|
Err(msg) => Err(format!("failed to load {}: {}", p.clone(), msg)),
|
||||||
|
}?;
|
||||||
|
let files = match metadata.is_dir() {
|
||||||
|
false => Ok(vec![p.clone()]),
|
||||||
|
true => match std::fs::read_dir(p.clone()) {
|
||||||
|
Ok(paths) => Ok(paths
|
||||||
|
.filter(|x| x.is_ok())
|
||||||
|
.map(|x| x.unwrap())
|
||||||
|
.filter(|x| x.metadata().unwrap().is_file())
|
||||||
|
.map(|x| x.path().display().to_string())
|
||||||
|
.filter(|x| !x.contains("/."))
|
||||||
|
.collect()),
|
||||||
|
Err(msg) => Err(format!("failed to read {}: {}", p.clone(), msg)),
|
||||||
|
},
|
||||||
|
}?;
|
||||||
|
assert!(files.len() > 0, "no files");
|
||||||
|
Ok(files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test_flags {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flags_files_unhidden_only() {
|
||||||
|
tests::with_dir(|d| {
|
||||||
|
std::fs::File::create(d.path().join("plain")).unwrap();
|
||||||
|
std::fs::File::create(d.path().join(".hidden")).unwrap();
|
||||||
|
|
||||||
|
let flags = Flags {
|
||||||
|
path: d.path().to_str().unwrap().to_string(),
|
||||||
|
add: None,
|
||||||
|
edit: false,
|
||||||
|
dry_run: true,
|
||||||
|
add_schedule: None,
|
||||||
|
};
|
||||||
|
let files = flags.files().expect("failed to files from dir");
|
||||||
|
assert_eq!(1, files.len());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn with_dir(mut foo: impl FnMut(tempdir::TempDir)) {
|
||||||
|
foo(tempdir::TempDir::new("").unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
mod v1 {
|
mod v1 {
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -1138,3 +1240,4 @@ mod v1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user