use std::{ffi::OsStr, fs::File, io::prelude::*, path::Path};
use anyhow::{Error, Result};
use crate::github::{handler::EventHandler, util::*, Client, DefaultEventHandler};
pub struct ClientBuilder<T>
where
T: std::fmt::Debug + EventHandler<GitHubClient = Client<T>> + Send + Sync + 'static,
{
handler: Option<T>,
auth: Option<Authorization>,
user_agent: Option<String>,
#[cfg(feature = "native")]
payload_size: Option<u64>,
}
impl<T> ClientBuilder<T>
where
T: std::fmt::Debug + EventHandler<GitHubClient = Client<T>> + Send + Sync + 'static,
{
pub fn new() -> Self {
Self::default()
}
pub fn event_handler(mut self, event_handler: T) -> Self {
self.handler = Some(event_handler);
self
}
#[cfg(feature = "native")]
pub fn payload_size(mut self, size: u64) -> Self {
self.payload_size = Some(size);
self
}
pub fn user_agent<V: Into<String>>(mut self, user_agent: V) -> Self {
self.user_agent = Some(user_agent.into());
self
}
pub fn credentials_file<P: AsRef<Path>>(self, file: P) -> Self {
let mut f = File::open(file).expect("ClientBuilder: Opening authorization file");
let mut contents = "".to_owned();
f.read_to_string(&mut contents)
.expect("ClientBuilder: Reading authorization file");
let auth: Authorization = toml::from_str::<OctocatConfig>(contents.as_str())
.expect("ClientBuilder: Parsing authorization file")
.to_personal_auth();
self.set_auth(Some(auth))
}
pub fn credentials_env_var<K: AsRef<OsStr>>(self, username_var: K, token_var: K) -> Self {
let auth = {
let username = std::env::var(username_var).expect("username not set!");
let token = std::env::var(token_var).expect("token not set!");
Authorization::PersonalToken { username, token }
};
self.set_auth(Some(auth))
}
pub fn personal_auth<V: Into<String>>(self, username: V, token: V) -> Self {
let auth = Authorization::PersonalToken {
username: username.into(),
token: token.into(),
};
self.set_auth(Some(auth))
}
fn set_auth(mut self, auth: Option<Authorization>) -> Self {
self.auth = auth;
self
}
pub fn build(self) -> Result<Client<T>> {
if self.handler.is_none() {
return Err(Error::from(BuildError::NoHandler));
}
Ok(Client::new(
self.handler.unwrap(),
self.auth,
self.user_agent,
#[cfg(feature = "native")]
self.payload_size,
))
}
}
impl ClientBuilder<DefaultEventHandler> {
pub fn build_unconfigured() -> Client<DefaultEventHandler> {
Client::default()
}
pub fn build_no_handler(self) -> Result<Client<DefaultEventHandler>> {
Ok(Client::new(
DefaultEventHandler::new(),
self.auth,
self.user_agent,
#[cfg(feature = "native")]
self.payload_size,
))
}
}
impl<T> Default for ClientBuilder<T>
where
T: std::fmt::Debug + EventHandler<GitHubClient = Client<T>> + Send + Sync + 'static,
{
fn default() -> Self {
Self {
handler: None,
auth: None,
#[cfg(feature = "native")]
payload_size: None,
user_agent: None,
}
}
}