1
2#[derive(clap::Subcommand)]
3pub enum Commands {
4 #[clap(about = "uri-tools")]
5 Uri {
6 #[clap(subcommand)]
7 command: uri::UriCommand,
8 },
9 #[clap(about = "json-tools")]
10 Json {
11 #[clap(subcommand)]
12 command: json::JsonCommand,
13 },
14 #[clap(about = "time-tools")]
15 Time {
16 #[clap(subcommand)]
17 command: time::TimeCommand,
18 },
19 #[clap(name = "qrcode", about = "qrcode-tools, alias 'qr'", alias = "qr")]
20 QrCode {
21 #[clap(subcommand)]
22 command: qrcode::QrCodeCommand,
23 },
24}
25
26pub trait Command {
27 fn run(&self) -> crate::Result<()>;
28}
29
30impl Command for Commands {
31 fn run(&self) -> crate::Result<()> {
32 match self {
33 Commands::Uri { command } => command.run(),
34 Commands::Json { command } => command.run(),
35 Commands::Time { command } => command.run(),
36 Commands::QrCode { command } => command.run(),
37 }
38 }
39}
40
41mod http_parser;
42pub mod uri;
43pub mod json;
44pub mod time;
45pub mod qrcode;
46
47
48#[cfg(feature = "read_stdin")]
49fn read_stdin() -> Option<String> {
50 use std::io::{BufRead, IsTerminal};
51 let stdin = std::io::stdin().lock();
52 if stdin.is_terminal() {
53 None
54 } else {
55 let mut lines = vec![];
56 for line in stdin.lines() {
57 match line {
58 Ok(line) => {
59 let _ = lines.push(line);
60 }
61 Err(err) => {
62 log::error!("read from stdin failed, {}", err);
63 break;
64 }
65 }
66 }
67 let string = lines.join("\n");
68 Some(string)
69 }
70}
71
72#[cfg(not(feature = "read_stdin"))]
73fn read_stdin() -> Option<String> {
74 None
75}
76