Skip to content

Commit

Permalink
add csv command
Browse files Browse the repository at this point in the history
  • Loading branch information
will-we committed Sep 9, 2024
1 parent cfd657f commit d1e789b
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 43 deletions.
88 changes: 81 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
[package]
name = "rustCli"
name = "rust-cli"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow="1.0.86"
clap = { version = "4.5.13", features = ["derive"] }
anyhow="1.0.87"
clap = { version = "4.5.17", features = ["derive"] }
csv = "1.3.0"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
4 changes: 4 additions & 0 deletions data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Name,Age,Occupation
Alice,30,Engineer
Bob,25,Designer
Charlie,35,Teacher
17 changes: 17 additions & 0 deletions output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"Name": "Alice",
"Age": 30,
"Occupation": "Engineer"
},
{
"Name": "Bob",
"Age": 25,
"Occupation": "Designer"
},
{
"Name": "Charlie",
"Age": 35,
"Occupation": "Teacher"
}
]
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod opts;

pub use opts::Opts;
56 changes: 23 additions & 33 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
use clap::Parser;

#[derive(Parser, Debug)]
#[command(name = "rustCli", version, about="rust命令行工具", long_about = None)]
struct Opts {
#[command(subcommand)]
cmd: SubCommand,
}

#[derive(Parser, Debug)]
enum SubCommand {
#[command(name = "csv", about = "读取csv文件并默认输出json文件")]
Csv(CsvOpts),
}
mod opts;

#[derive(Parser, Debug)]
struct CsvOpts {
/// Name of the person to greet
#[arg(short, long)]
input: String,
use crate::opts::{Opts, Person, SubCommand};
use clap::Parser;
use csv::Reader;
use std::fs;

/// Output file name
#[arg(short, long, default_value = "output.json")]
output: String,
/// rust-li csv -i input.csv -o output.json -d ","
fn main() -> anyhow::Result<()> {
let opts = Opts::parse();
match opts.cmd {
SubCommand::Csv(opts) => {
let mut reader = Reader::from_path(opts.input)?;

/// Delimiter to use for output file
#[arg(short, long, default_value = ",")]
delimiter: String,
let mut persons: Vec<Person> = Vec::new();
// 读取csv文件
for record in reader.deserialize() {
let person: Person = record?;
println!(" {:?}", person);
persons.push(person);
}

#[arg(long, default_value_t = true)]
header: bool,
}

/// rustCli csv -i input.csv -o output.json -d ","
fn main() {
let opts = Opts::parse();
println!("{:?}", opts);
// 输出json文件
let result = serde_json::to_string_pretty(&persons)?;
Ok(fs::write(opts.output, result)?)
}
}
}
52 changes: 52 additions & 0 deletions src/opts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::path;
use clap::Parser;
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct Person {
name: String,
age: u8,
occupation: String,
}

#[derive(Parser, Debug)]
#[command(name = "rustCli", version, about="rust命令行工具", long_about = None)]
pub struct Opts {
#[command(subcommand)]
pub(crate) cmd: SubCommand,
}

#[derive(Parser, Debug)]
pub enum SubCommand {
#[command(name = "csv", about = "读取csv文件并默认输出json文件")]
Csv(CsvOpts),
}

#[derive(Parser, Debug)]
pub struct CsvOpts {
/// 文件输入的路径,必填
#[arg(short, long, required = true, value_parser = validate_path)]
pub input: String,

/// 文件输入的路径,默认 output.json
#[arg(short, long, default_value = "output.json")]
pub output: String,

/// 文件分隔符,默认","
#[arg(short, long, default_value = ",")]
pub delimiter: String,

/// 是否有标题行,默认true
#[arg(long, default_value_t = true)]
pub header: bool,
}

/// 自定义参数校验器: 校验文件路径是否存在
fn validate_path(path: &str) -> Result<String, String> {
if path::Path::new(path).exists() {
Ok(path.to_string())
} else {
Err(format!("{} 文件不存在", path))
}
}

0 comments on commit d1e789b

Please sign in to comment.