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); }

Rust:


[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