use clap::Parser;
use anyhow::{Result, Context};
use std::path::PathBuf;
use std::fs;
#[derive(Parser)]
#[command(name = "wordcount")]
#[command(about = "统计文件中的单词数、行数、字符数")]
struct Args {
files: Vec<PathBuf>,
#[arg(short = 'l', long)]
lines: bool,
#[arg(short = 'w', long)]
words: bool,
#[arg(short = 'c', long)]
chars: bool,
}
#[derive(Default)]
struct Stats {
lines: usize,
words: usize,
chars: usize,
}
fn count(content: &str) -> Stats {
Stats {
lines: content.lines().count(),
words: content.split_whitespace().count(),
chars: content.chars().count(),
}
}
fn main() -> Result<()> {
let args = Args::parse();
let show_all = !args.lines && !args.words && !args.chars;
for path in &args.files {
let content = fs::read_to_string(path)
.context(format!("无法读取文件: {}", path.display()))?;
let stats = count(&content);
let mut parts = vec![];
if show_all || args.lines {
parts.push(format!("{}", stats.lines));
}
if show_all || args.words {
parts.push(format!("{}", stats.words));
}
if show_all || args.chars {
parts.push(format!("{}", stats.chars));
}
println!("{} {}", parts.join("\t"), path.display());
}
Ok(())
}