#[cfg(test)] mod test;
pub mod substrate;
use std::{env, sync::Arc};
use githuber::api::{ApiExt, Method::*};
use reqwest::{
Client,
header::{ACCEPT, USER_AGENT},
};
use serde::{Deserialize, de::DeserializeOwned};
use crate::{http::CLIENT, prelude::*};
#[derive(Debug, Clone)]
pub struct ApiClient {
inner: Arc<Client>,
token: String,
}
impl ApiClient {
const PER_PAGE: u8 = 100;
const USER_AGENT: &'static str = "subalfred-api-client";
pub fn new() -> Result<Self> {
Ok(Self { inner: CLIENT.clone(), token: get_github_token()? })
}
pub async fn request<R, D>(&self, request: &R) -> Result<D>
where
R: ApiExt,
D: DeserializeOwned,
{
let api = request.api();
let payload_params = request.payload_params();
tracing::trace!("Request({api}),Payload({payload_params:?})");
let response = match R::METHOD {
Delete => todo!(),
Get => self
.inner
.get(api)
.header(ACCEPT, R::ACCEPT)
.header(USER_AGENT, Self::USER_AGENT)
.bearer_auth(&self.token)
.query(&payload_params),
Patch => todo!(),
Post => todo!(),
Put => todo!(),
}
.send()
.await
.map_err(error::Generic::Reqwest)?
.json::<D>()
.await
.map_err(error::Generic::Reqwest)?;
Ok(response)
}
pub async fn request_auto_retry<R, D>(&self, request: &R) -> D
where
R: Clone + ApiExt,
D: DeserializeOwned,
{
for i in 0_u16.. {
match self.request::<R, D>(request).await {
Ok(r) => return r,
Err(e) => {
tracing::warn!("request failed dut to: {e:?}, retried {i} times");
},
}
}
unreachable!(
"[core::github] there is an infinity loop before; hence this block can never be reached; qed"
)
}
}
#[derive(Debug, Deserialize)]
struct Commits {
commits: Vec<Commit>,
}
#[derive(Debug, Deserialize)]
struct Commit {
sha: String,
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Clone, Debug, Deserialize)]
pub struct PullRequest {
pub title: String,
pub html_url: String,
pub labels: Vec<Label>,
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Clone, Debug, Deserialize)]
pub struct Label {
pub name: String,
}
fn get_github_token() -> Result<String> {
Ok(env::var("GITHUB_TOKEN").map_err(error::Github::NoTokenFound)?)
}