1use crate::error::Result;
2use crate::executor::GhExecutor;
3
4pub trait GhCommand {
7 fn build_args(&self) -> Vec<String>;
9
10 fn execute(&self, executor: &GhExecutor) -> Result<String> {
12 let args = self.build_args();
13 executor.execute(&args)
14 }
15}
16
17pub trait CommandBuilder: Sized {
19 fn flag(self, flag: &str) -> Self;
21
22 fn option(self, key: &str, value: &str) -> Self;
24}
25
26#[derive(Debug, Clone)]
28pub struct BaseCommand {
29 pub(crate) args: Vec<String>,
30}
31
32impl BaseCommand {
33 pub fn new(subcommand: &str) -> Self {
35 Self {
36 args: vec![subcommand.to_string()],
37 }
38 }
39
40 pub fn with_subcommands(subcommands: &[&str]) -> Self {
42 Self {
43 args: subcommands.iter().map(|s| s.to_string()).collect(),
44 }
45 }
46
47 pub fn arg(mut self, arg: &str) -> Self {
49 self.args.push(arg.to_string());
50 self
51 }
52
53 pub fn args(mut self, args: &[&str]) -> Self {
55 self.args.extend(args.iter().map(|s| s.to_string()));
56 self
57 }
58}
59
60impl CommandBuilder for BaseCommand {
61 fn flag(mut self, flag: &str) -> Self {
62 self.args.push(flag.to_string());
63 self
64 }
65
66 fn option(mut self, key: &str, value: &str) -> Self {
67 self.args.push(key.to_string());
68 self.args.push(value.to_string());
69 self
70 }
71}
72
73impl GhCommand for BaseCommand {
74 fn build_args(&self) -> Vec<String> {
75 self.args.clone()
76 }
77}