CLI clap crate derive #[derive(Parser)] #[derive(Subcommand)] match
serde + serde_jsonJSON /#[derive(Serialize, Deserialize)] serde_json::to_string_pretty() serde_json::from_str()
Result<T, E> + ? → main if let Err(e) = ... { eprintln!("{e:#}"); exit(1); }
[dependencies]
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"use clap::{Parser, Subcommand};
use serde::{Serialize, Deserialize};
#[derive(Parser)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Add { name: String, score: u32 },
List,
Search { name: String },
Delete { name: String },
}
#[derive(Serialize, Deserialize, Clone, Debug)]
struct Student {
name: String,
score: u32,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = std::fs::read_to_string("students.json")
.map(|s| serde_json::from_str(&s).unwrap_or_default())
.unwrap_or_else(|_| Vec::<Student>::new());
let cli = Cli::parse();
match cli.command {
Commands::Add { name, score } => { /* push + write */ }
Commands::List => { /* iter + print */ }
Commands::Search { name } => { /* filter + find */ }
Commands::Delete { name } => { /* retain */ }
}
Ok(())
}: —
let mut students: Vec<(i32, i32, i32, i32)> = vec![];
// (total, chinese, id) → sort → 5