gh_cli_rs/
client.rs

1use crate::commands::{issue::IssueCommands, pr::PrCommands, repo::RepoCommands};
2use crate::error::Result;
3use crate::executor::GhExecutor;
4use std::sync::Arc;
5
6/// Main GitHub CLI client
7/// This is the entry point for all GitHub CLI operations
8#[derive(Clone)]
9pub struct GhClient {
10    executor: Arc<GhExecutor>,
11}
12
13impl Default for GhClient {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl GhClient {
20    /// Create a new GitHub CLI client with default settings
21    pub fn new() -> Self {
22        Self {
23            executor: Arc::new(GhExecutor::default()),
24        }
25    }
26
27    /// Start building a custom GitHub CLI client
28    pub fn builder() -> GhClientBuilder {
29        GhClientBuilder::new()
30    }
31
32    /// Check if GitHub CLI is installed
33    pub fn check_installation(&self) -> Result<String> {
34        self.executor.check_installation()
35    }
36
37    /// Access repository commands
38    pub fn repo(&self) -> RepoCommands {
39        RepoCommands::new(self.executor.clone())
40    }
41
42    /// Access pull request commands
43    pub fn pr(&self) -> PrCommands {
44        PrCommands::new(self.executor.clone())
45    }
46
47    /// Access issue commands
48    pub fn issue(&self) -> IssueCommands {
49        IssueCommands::new(self.executor.clone())
50    }
51}
52
53/// Builder for GhClient using the Builder Pattern
54/// This allows for flexible configuration
55pub struct GhClientBuilder {
56    gh_path: Option<String>,
57}
58
59impl GhClientBuilder {
60    /// Create a new builder
61    pub fn new() -> Self {
62        Self { gh_path: None }
63    }
64
65    /// Set a custom path to the gh binary
66    pub fn gh_path(mut self, path: impl Into<String>) -> Self {
67        self.gh_path = Some(path.into());
68        self
69    }
70
71    /// Build the GhClient
72    pub fn build(self) -> GhClient {
73        let executor = if let Some(gh_path) = self.gh_path {
74            Arc::new(GhExecutor::new(gh_path))
75        } else {
76            Arc::new(GhExecutor::default())
77        };
78
79        GhClient { executor }
80    }
81}
82
83impl Default for GhClientBuilder {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn test_client_creation() {
95        let client = GhClient::new();
96        assert!(Arc::strong_count(&client.executor) >= 1);
97    }
98
99    #[test]
100    fn test_builder_pattern() {
101        let client = GhClient::builder().gh_path("/usr/local/bin/gh").build();
102        assert!(Arc::strong_count(&client.executor) >= 1);
103    }
104}