use crate::github::{error::GitHubError, util::spawn_task};
use crate::runtime::AsyncTask;
use octocrab::{Octocrab, models::Author};
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UserSearchSort {
Followers,
Repositories,
Joined,
}
impl UserSearchSort {
#[inline]
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Followers => "followers",
Self::Repositories => "repositories",
Self::Joined => "joined",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SearchOrder {
Asc,
Desc,
}
impl SearchOrder {
#[inline]
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Asc => "asc",
Self::Desc => "desc",
}
}
}
#[inline]
pub(crate) fn search_users(
inner: Arc<Octocrab>,
query: impl Into<String>,
sort: Option<UserSearchSort>,
order: Option<SearchOrder>,
page: Option<u32>,
per_page: Option<u8>,
) -> AsyncTask<Result<octocrab::Page<Author>, GitHubError>> {
let query = query.into();
spawn_task(async move {
if query.is_empty() {
return Err(GitHubError::InvalidInput(
"search query cannot be empty".into(),
));
}
if let Some(p) = page
&& p < 1
{
return Err(GitHubError::InvalidInput("page must be >= 1".into()));
}
if let Some(pp) = per_page
&& !(1..=100).contains(&pp)
{
return Err(GitHubError::InvalidInput(
"per_page must be between 1 and 100".into(),
));
}
let mut request = inner.search().users(&query);
if let Some(s) = sort {
request = request.sort(s.as_str());
}
if let Some(o) = order {
request = request.order(o.as_str());
}
if let Some(p) = page {
request = request.page(p);
}
if let Some(pp) = per_page {
request = request.per_page(pp);
}
let results = request.send().await.map_err(GitHubError::from)?;
Ok(results)
})
}