Files
QRGen/cli/src/main.rs
T

109 lines
3.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use clap::Parser;
use qr_core::qr::{QrCode, QrConfig, VersionMode};
use qr_core::version::EcLevel;
use std::path::Path;
#[derive(Parser)]
#[command(name = "qrgen", about = "QR 码生成器 — 从零手搓的 ISO/IEC 18004 实现")]
struct Args {
/// 要编码的内容
content: String,
/// 输出文件 (.png 或 .svg),不指定则输出终端 ASCII
#[arg(short = 'o', long)]
output: Option<String>,
/// 纠错级别 [L/M/Q/H] [default: M]
#[arg(short = 'l', long, default_value = "M")]
level: String,
/// 手动指定版本 (1-40),不指定则自动选择
#[arg(short = 'v', long)]
version: Option<u8>,
/// 模块像素大小(仅 PNG[default: 4]
#[arg(short = 's', long, default_value = "4")]
size: u8,
/// 白边模块数 [default: 4]
#[arg(short = 'm', long, default_value = "4")]
margin: u8,
/// 反色(黑底白码)
#[arg(long)]
invert: bool,
}
fn main() -> anyhow::Result<()> {
let args = Args::parse();
let level = match args.level.to_uppercase().as_str() {
"L" => EcLevel::L,
"M" => EcLevel::M,
"Q" => EcLevel::Q,
"H" => EcLevel::H,
_ => anyhow::bail!("无效纠错级别: {}。支持 L/M/Q/H", args.level),
};
let version = match args.version {
Some(v) => {
if !(1..=40).contains(&v) {
anyhow::bail!("无效版本号: {}。支持 1-40", v);
}
VersionMode::Fixed(v)
}
None => VersionMode::Auto,
};
let config = QrConfig {
level,
version,
margin: args.margin,
};
let qr =
QrCode::encode(&args.content, config).map_err(|e| anyhow::anyhow!("编码失败: {}", e))?;
match args.output {
Some(path) => {
let ext = Path::new(&path)
.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_lowercase();
match ext.as_str() {
"png" => {
let bytes = qr.to_png_bytes(args.size)?;
std::fs::write(&path, bytes)?;
println!(
"已生成: {} (版本 {}, {}×{} 模块, {} 级纠错)",
path,
qr.version.0,
qr.size(),
qr.size(),
match qr.level {
EcLevel::L => "L",
EcLevel::M => "M",
EcLevel::Q => "Q",
EcLevel::H => "H",
}
);
}
"svg" => {
let svg = qr.to_svg();
std::fs::write(&path, svg)?;
println!("已生成: {} (版本 {}, SVG 格式)", path, qr.version.0);
}
_ => anyhow::bail!("不支持的文件格式: .{}。支持 .png / .svg", ext),
}
}
None => {
// 终端 ASCII 输出
println!("{}", qr.to_ascii(args.invert));
}
}
Ok(())
}