#[macro_export]
macro_rules! make_single_page_api {
($function_name:ident, $endpoint:expr, $return_type:ty) => {
impl GitHubApi {
pub fn $function_name(&self, owner: &str, repository: &str) -> Response<$return_type> {
let method = format!("repos/{}/{}/{}", owner, repository, $endpoint);
let (text, limit_remaining_reset, next_page) =
self.api_get_call(&method, 1, 100)?;
Ok(GitHubApiResult {
result: parse_json(&text)?,
raw_result: text,
limits: limit_remaining_reset,
owner: Some(owner.to_string()),
repository: Some(repository.to_string()),
next_page,
})
}
}
};
}
#[macro_export]
macro_rules! make_paginated_api {
($paginator_function_name:ident, $page_function_name:ident, $endpoint:expr, $paginator_name:ident, $return_type:ty) => {
impl GitHubApi {
pub fn $page_function_name(
&self,
owner: &str,
repository: &str,
page: u64,
) -> Response<Vec<$return_type>> {
let method = format!("repos/{}/{}/{}", owner, repository, $endpoint);
let (text, limit_remaining_reset, next_page) =
self.api_get_call(&method, page, 100)?;
Ok(GitHubApiResult {
result: parse_json(&text)?,
raw_result: text,
limits: limit_remaining_reset,
owner: Some(owner.to_string()),
repository: Some(repository.to_string()),
next_page,
})
}
pub fn $paginator_function_name(
&self,
owner: &str,
repository: &str,
) -> $paginator_name {
$paginator_name::new(&self, owner, repository)
}
}
pub struct $paginator_name<'a> {
github_api: &'a GitHubApi,
owner: String,
repository: String,
next_page: Option<u64>,
}
impl<'a> $paginator_name<'a> {
pub fn new(github_api: &'a GitHubApi, owner: &str, repository: &str) -> Self {
Self {
github_api,
owner: owner.to_string(),
repository: repository.to_string(),
next_page: Some(1),
}
}
pub fn has_items(&self) -> Result<bool, GitHubApiError> {
let method = format!("repos/{}/{}/{}", self.owner, self.repository, $endpoint);
let (text, _, _) = self.github_api.api_get_call(&method, 1, 1)?;
let response: Vec<$return_type> = parse_json(&text)?;
Ok(!response.is_empty())
}
}
impl<'a> Iterator for $paginator_name<'a> {
type Item = GitHubApiResult<Vec<$return_type>>;
fn next(&mut self) -> Option<Self::Item> {
match self.next_page {
Some(page_number) => {
let requested_page = self.github_api.$page_function_name(
&self.owner,
&self.repository,
page_number,
);
match requested_page {
Ok(page) => {
self.next_page = page.next_page.clone();
Some(page)
}
Err(error) => {
eprintln!("Error: {:#?}", error);
None
}
}
}
None => None,
}
}
}
};
}