gh_cli_rs/
command.rs

1use crate::error::Result;
2use crate::executor::GhExecutor;
3
4/// Base trait for all GitHub CLI command builders
5/// This implements the Command Pattern
6pub trait GhCommand {
7    /// Build the command arguments
8    fn build_args(&self) -> Vec<String>;
9
10    /// Execute the command and return raw string output
11    fn execute(&self, executor: &GhExecutor) -> Result<String> {
12        let args = self.build_args();
13        executor.execute(&args)
14    }
15}
16
17/// Helper trait for building commands with a fluent interface
18pub trait CommandBuilder: Sized {
19    /// Add a flag (e.g., "--web")
20    fn flag(self, flag: &str) -> Self;
21
22    /// Add a flag with a value (e.g., "--repo", "owner/name")
23    fn option(self, key: &str, value: &str) -> Self;
24}
25
26/// Base command builder with common functionality
27#[derive(Debug, Clone)]
28pub struct BaseCommand {
29    pub(crate) args: Vec<String>,
30}
31
32impl BaseCommand {
33    /// Create a new base command with the given subcommand
34    pub fn new(subcommand: &str) -> Self {
35        Self {
36            args: vec![subcommand.to_string()],
37        }
38    }
39
40    /// Add multiple subcommands (e.g., ["pr", "list"])
41    pub fn with_subcommands(subcommands: &[&str]) -> Self {
42        Self {
43            args: subcommands.iter().map(|s| s.to_string()).collect(),
44        }
45    }
46
47    /// Add an argument
48    pub fn arg(mut self, arg: &str) -> Self {
49        self.args.push(arg.to_string());
50        self
51    }
52
53    /// Add multiple arguments
54    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}