dev_kit/command/qrcode/
mod.rs

1use 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;