rp_cli/
clap_rp.rs

1use crate::handler::Handler;
2use crate::input::{DownloadInput, FmtInput, RunInput, ShareInput};
3use clap::{Args, Parser, Subcommand};
4use std::path::PathBuf;
5
6#[derive(Debug, Parser)]
7pub struct Rp {
8    #[clap(subcommand)]
9    command: RpSubCommand,
10}
11
12impl Rp {
13    pub fn start(&self) -> Result<(), Box<dyn std::error::Error>> {
14        let mut handler = Handler::new();
15
16        match &self.command {
17            RpSubCommand::Run(args) => {
18                let input = args.input();
19                handler.run(input)?;
20                Ok(())
21            }
22            RpSubCommand::Fmt(args) => {
23                let input = args.input();
24                handler.fmt(input)?;
25                Ok(())
26            }
27            RpSubCommand::Share(args) => {
28                let input = args.input();
29                handler.share(input)?;
30                Ok(())
31            }
32            RpSubCommand::Download(args) => {
33                let input = args.input();
34                handler.download(input)?;
35                Ok(())
36            } // error handling...
37        }
38    }
39}
40
41#[derive(Debug, PartialEq, Subcommand)]
42pub enum RpSubCommand {
43    #[clap(name = "run")]
44    Run(RunArgs),
45
46    #[clap(name = "fmt")]
47    Fmt(FmtArgs),
48
49    #[clap(name = "share")]
50    Share(ShareArgs),
51
52    #[clap(name = "download")]
53    Download(DownloadArgs),
54}
55
56#[derive(Args, PartialEq, Debug)]
57pub struct RunArgs {
58    // TODO: support other run_type (build, test, wasm,,,)
59    // https://github.com/clap-rs/clap/blob/master/examples/tutorial_derive/04_01_enum.rs
60    // run_type: ENUM
61    #[clap(long = "mode", default_value = "debug", required = false)]
62    mode: String,
63
64    #[clap(long = "channel", default_value = "stable", required = false)]
65    channel: String,
66
67    #[clap(long = "edition", default_value = "2021", required = false)]
68    edition: String,
69
70    #[clap(long = "backtrace", parse(try_from_str = true_or_false), default_value = "false", required = false)]
71    backtrace: bool,
72
73    #[clap(required = true, parse(from_os_str))]
74    file_path: PathBuf,
75}
76
77impl RunArgs {
78    fn input(&self) -> RunInput {
79        RunInput {
80            mode: self.mode.clone(),
81            channel: self.channel.clone(),
82            edition: self.edition.clone(),
83            backtrace: self.backtrace,
84            file_path: self.file_path.clone(),
85        }
86    }
87}
88
89#[derive(Args, PartialEq, Debug)]
90pub struct FmtArgs {
91    #[clap(long = "edition", default_value = "2021", required = false)]
92    edition: String,
93
94    #[clap(required = true, parse(from_os_str))]
95    file_path: PathBuf,
96}
97
98impl FmtArgs {
99    fn input(&self) -> FmtInput {
100        FmtInput {
101            edition: self.edition.clone(),
102            file_path: self.file_path.clone(),
103        }
104    }
105}
106
107#[derive(Args, PartialEq, Debug)]
108pub struct ShareArgs {
109    #[clap(required = true, parse(from_os_str))]
110    file_path: PathBuf,
111}
112
113impl ShareArgs {
114    fn input(&self) -> ShareInput {
115        ShareInput {
116            file_path: self.file_path.clone(),
117        }
118    }
119}
120
121#[derive(Args, PartialEq, Debug)]
122pub struct DownloadArgs {
123    #[clap(required = true)]
124    id_or_url: String,
125}
126
127impl DownloadArgs {
128    fn input(&self) -> DownloadInput {
129        DownloadInput {
130            id_or_url: self.id_or_url.clone(),
131        }
132    }
133}
134
135fn true_or_false(s: &str) -> Result<bool, &'static str> {
136    match s {
137        "true" => Ok(true),
138        "false" => Ok(false),
139        _ => Err("expected `true` or `false`"),
140    }
141}