dev_kit/command/qrcode/
mod.rs1use crate::command::{Command, StringInput};
2use crate::command::qrcode::generator::QrCodeImageVal;
3use derive_more::{Deref, FromStr};
4use qrcode::Version;
5use std::ops::Deref;
6use std::path::PathBuf;
7use strum::Display;
8
9#[derive(clap::Args)]
10pub struct QrCodeArgs {
11 #[arg(help = "QR code content", default_value = "")]
12 content: QrContent,
13 #[arg(
14 short,
15 long,
16 help = r#"
17 QR code error correction level, alias 'ecl'
18 7%: Low error correction level, alias 'l'
19 15%: Medium error correction level, alias 'm'
20 25%: Quartile error correction level, alias 'q'
21 30%: High error correction level, alias 'h'
22 "#,
23 alias = "ecl",
24 default_value = "q"
25 )]
26 ec_level: QrEcLevel,
27 #[arg(
28 short,
29 long,
30 help = r#"
31 QR code version,
32 In QR code terminology, Version means the size of the generated image. Larger version means the size of code is larger, and therefore can carry more information.
33 A normal QR code version. The parameter should be between 1 and 40.
34 QR size: version * 4 + 17
35 "#,
36 default_value = "auto"
37 )]
38 version: QrVersion,
39 #[arg(
40 short,
41 long,
42 help = "QR code output type, alias 'type'",
43 alias = "type",
44 default_value = "text"
45 )]
46 output_type: OutputType,
47 #[arg(short, long, help = "QR code output file")]
48 file: Option<PathBuf>,
49 #[arg(short, long, help = "plain text output")]
50 plain: bool,
51}
52
53#[derive(Debug, Clone, Deref, FromStr)]
54pub struct QrContent(StringInput);
55
56#[derive(Debug, Copy, Clone, Deref)]
57pub struct QrEcLevel(qrcode::EcLevel);
58
59#[derive(Debug, Copy, Clone)]
60pub enum QrVersion {
61 Auto,
62 Version(Version),
63}
64
65#[derive(Debug, Copy, Clone, FromStr, Default, Display)]
66pub enum OutputType {
67 #[default]
68 Text,
69 Image,
70 Svg,
71}
72
73impl Command for QrCodeArgs {
74 fn run(&self) -> crate::Result<()> {
75 let Self {
76 content,
77 ec_level,
78 version,
79 output_type,
80 file,
81 plain,
82 } = self;
83 let result = generator::generate(content, ec_level, version, *output_type);
84 match result {
85 Ok(result) => {
86 let show_detail = !plain;
87 if show_detail {
88 print!(
89 r#"
90Generate QR Code
91Error correction level: {}
92Version: {}
93Output Type: {}
94"#,
95 result.ec_level,
96 result.version,
97 result.out_put_type()
98 );
99 }
100 match result.deref() {
101 QrCodeImageVal::Text(text) => {
102 if let Some(file) = file {
103 match std::fs::write(file, text) {
104 Ok(_) => {
105 if show_detail {
106 print!("Write QR Code to ")
107 }
108 println!("{}", file.display())
109 }
110 Err(err) => eprintln!("{}", err),
111 }
112 } else {
113 println!("{}", text);
114 }
115 Ok(())
116 }
117 QrCodeImageVal::Image(path) | QrCodeImageVal::Svg(path) => {
118 match if let Some(file_path) = file {
119 std::fs::copy(path, file_path).map(|_| file_path)
120 } else {
121 Ok(path)
122 } {
123 Ok(path) => {
124 if show_detail {
125 print!("Write QR Code to ")
126 }
127 println!("{}", path.display())
128 }
129 Err(err) => {
130 eprintln!("{}", err)
131 }
132 }
133 Ok(())
134 }
135 }
136 }
137 Err(err) => {
138 eprintln!("Generate QR Code failed, {}", err);
139 Ok(())
140 }
141 }
142 }
143}
144
145pub mod generator;