use_github_api/client/
builder.rs

1use std::error::Error as StdError;
2
3// This should work without this `cfg`, but the doctest fails without it (even though it is ignored).
4#[cfg(feature = "auth")]
5use crate::CreationError;
6use crate::GithubClient;
7
8#[non_exhaustive]
9/// A `GithubClient` builder.
10/// Allows building a `GithubClient` while still setting options like the base URL and auth token. Only useful when either the `auth` or `enterprise` feature enabled.
11/// # Examples
12/// ```rust,ignore
13/// use use_github_api::{GithubClient, GithubClientBuilder};
14/// // If `enterprise` is enabled
15/// let client = GithubClientBuilder::new().auth("adS*lkjha(&W3").base_url("https://gh.enterprise.org/api/v3").build().unwrap();
16/// // If `enterprise` is not enabled
17/// let client = GithubClientBuilder::new().auth("ghp_kajshdkja").build().unwrap();
18/// ```
19#[cfg_attr(docsrs, doc(cfg(feature = "auth")))]
20pub struct GithubClientBuilder<'a> {
21    #[cfg(feature = "enterprise")]
22    base_url: Option<&'a str>,
23    #[cfg(feature = "auth")]
24    auth_token: Option<&'a str>,
25}
26
27impl<'a> GithubClientBuilder<'a> {
28    /// Creates a new `GithubClientBuilder`.
29    pub fn new() -> Self {
30        Self {
31            #[cfg(feature = "auth")]
32            auth_token: None,
33            #[cfg(feature = "enterprise")]
34            base_url: None,
35        }
36    }
37
38    /// Builds the builder and returns a client.
39    /// # Errors
40    /// If either the auth token or the base url is missing, this will error out.
41    pub fn build(self) -> Result<GithubClient<'a>, Box<dyn StdError>> {
42        #[cfg(all(feature = "auth", feature = "enterprise"))]
43        return match self.auth_token {
44            None => Err(CreationError::auth_token_not_provided().into()),
45            Some(token) => match self.base_url {
46                None => Err(CreationError::base_url_not_provided().into()),
47                Some(base_url) => GithubClient::new(base_url, token),
48            },
49        };
50        #[cfg(feature = "auth")]
51        #[cfg(not(feature = "enterprise"))]
52        return match self.auth_token {
53            None => Err(CreationError::auth_token_not_provided().into()),
54            Some(token) => GithubClient::new(token),
55        };
56    }
57
58    #[cfg(any(feature = "auth", doc))]
59    /// Sets the auth token.
60    /// # Examples
61    /// ```rust
62    /// # #[cfg(feature = "auth")]
63    /// # {
64    /// # use use_github_api::GithubClientBuilder;
65    /// let builder = GithubClientBuilder::new();
66    /// let builder = builder.auth("my auth token");
67    /// // Build client and do stuff
68    /// # }
69    /// ```
70    pub fn auth(mut self, auth_token: &'a str) -> Self {
71        self.auth_token = Some(auth_token);
72        self
73    }
74
75    #[cfg(any(feature = "enterprise", doc))]
76    /// Sets the base url.
77    /// # Examples
78    /// ```rust
79    /// # #[cfg(feature = "enterprise")]
80    /// # {
81    /// # use use_github_api::GithubClientBuilder;
82    /// let builder = GithubClientBuilder::new();
83    /// let builder = builder.base_url("https://something.com/api/v3");
84    /// // Build client and do stuff
85    /// # }
86    /// ```
87    pub fn base_url(mut self, base_url: &'a str) -> Self {
88        self.base_url = Some(base_url);
89        self
90    }
91}
92
93impl<'a> Default for GithubClientBuilder<'a> {
94    fn default() -> Self {
95        Self::new()
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use crate::constants::FAKE_TOKEN;
102
103    use super::*;
104    #[test]
105    fn creates_new() {
106        let builder = GithubClientBuilder::new();
107        assert_eq!(builder.auth_token, None);
108        #[cfg(feature = "enterprise")]
109        assert_eq!(builder.base_url, None);
110    }
111
112    #[test]
113    fn sets_auth() {
114        let builder = GithubClientBuilder::new();
115        let token = "Some token";
116        assert_eq!(builder.auth(token).auth_token, Some(token));
117    }
118
119    #[test]
120    #[cfg(feature = "enterprise")]
121    fn sets_base_url() {
122        let builder = GithubClientBuilder::new();
123        let base_url = "something.com";
124        assert_eq!(builder.base_url(base_url).base_url, Some(base_url));
125    }
126
127    #[test]
128    #[should_panic(expected = "CreationError { kind: AuthTokenNotProvided }")]
129    fn err_on_no_token() {
130        let builder = GithubClientBuilder::new();
131        builder.build().unwrap();
132    }
133
134    #[test]
135    #[cfg(feature = "enterprise")]
136    #[should_panic(expected = "CreationError { kind: BaseUrlNotProvided }")]
137    fn err_on_no_base_url() {
138        let builder = GithubClientBuilder::new();
139        builder.auth(FAKE_TOKEN).build().unwrap();
140    }
141
142    #[test]
143    fn builds_client() {
144        let builder = GithubClientBuilder::new();
145        #[cfg(not(feature = "enterprise"))]
146        let client = builder
147            .auth(FAKE_TOKEN)
148            .build()
149            .expect("Should build client");
150        #[cfg(feature = "enterprise")]
151        let client = builder
152            .auth(FAKE_TOKEN)
153            .base_url("https://something.something.com/api/v3")
154            .build()
155            .expect("Should build client");
156        assert_eq!(client.auth_token, FAKE_TOKEN);
157        #[cfg(feature = "enterprise")]
158        assert_eq!(client.base_url, "https://something.something.com/api/v3");
159    }
160}