1use crate::commands::{issue::IssueCommands, pr::PrCommands, repo::RepoCommands};
2use crate::error::Result;
3use crate::executor::GhExecutor;
4use std::sync::Arc;
5
6#[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 pub fn new() -> Self {
22 Self {
23 executor: Arc::new(GhExecutor::default()),
24 }
25 }
26
27 pub fn builder() -> GhClientBuilder {
29 GhClientBuilder::new()
30 }
31
32 pub fn check_installation(&self) -> Result<String> {
34 self.executor.check_installation()
35 }
36
37 pub fn repo(&self) -> RepoCommands {
39 RepoCommands::new(self.executor.clone())
40 }
41
42 pub fn pr(&self) -> PrCommands {
44 PrCommands::new(self.executor.clone())
45 }
46
47 pub fn issue(&self) -> IssueCommands {
49 IssueCommands::new(self.executor.clone())
50 }
51}
52
53pub struct GhClientBuilder {
56 gh_path: Option<String>,
57}
58
59impl GhClientBuilder {
60 pub fn new() -> Self {
62 Self { gh_path: None }
63 }
64
65 pub fn gh_path(mut self, path: impl Into<String>) -> Self {
67 self.gh_path = Some(path.into());
68 self
69 }
70
71 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}