feat: Implement list command with tag aggregation and CLI parsing

This commit is contained in:
Moritz Böhme 2025-02-23 15:51:12 +01:00
parent bce4b3eb86
commit 4dd9edee61
2 changed files with 74 additions and 2 deletions

View file

@ -5,3 +5,4 @@ edition = "2021"
[dependencies]
thiserror = "1.0"
clap = { version = "4.4", features = ["derive"] }

View file

@ -1,5 +1,76 @@
mod tag_engine;
fn main() {
println!("Hello, world!");
use std::collections::BTreeSet;
use std::error::Error;
use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// Files to process
#[arg(required = true)]
files: Vec<String>,
}
fn list_tags(files: &[String]) -> Result<Vec<String>, Box<dyn Error>> {
let mut unique_tags = BTreeSet::new();
for file in files {
if let Ok((_, tags, _)) = tag_engine::parse_tags(file) {
unique_tags.extend(tags);
}
}
Ok(unique_tags.into_iter().collect())
}
fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
let tags = list_tags(&cli.files)?;
for tag in tags {
println!("{}", tag);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_list_tags_empty() {
let files = Vec::new();
let tags = list_tags(&files).unwrap();
assert!(tags.is_empty());
}
#[test]
fn test_list_tags_single_file() {
let files = vec!["document.txt -- tag1 tag2".to_string()];
let tags = list_tags(&files).unwrap();
assert_eq!(tags, vec!["tag1", "tag2"]);
}
#[test]
fn test_list_tags_multiple_files() {
let files = vec![
"doc1.txt -- tag1 tag2".to_string(),
"doc2.txt -- tag2 tag3".to_string(),
];
let tags = list_tags(&files).unwrap();
assert_eq!(tags, vec!["tag1", "tag2", "tag3"]);
}
#[test]
fn test_list_tags_with_invalid() {
let files = vec![
"valid.txt -- good tag1".to_string(),
"invalid.txt -- bad:tag".to_string(),
];
let tags = list_tags(&files).unwrap();
assert_eq!(tags, vec!["good", "tag1"]);
}
}