use http::header::HeaderMap;
use http::header::ACCEPT;
use serde::Serialize;
use crate::models::activity::StarredRepository;
use crate::Octocrab;
use crate::Page;
use crate::Result;
pub struct StarringHandler<'octo> {
crab: &'octo Octocrab,
}
impl<'octo> StarringHandler<'octo> {
pub(crate) fn new(crab: &'octo Octocrab) -> Self {
Self { crab }
}
pub fn list_repos_starred_by_user(
&self,
username: impl Into<String>,
) -> ListReposStarredByUserBuilder<'_> {
ListReposStarredByUserBuilder::new(self.crab, username)
}
pub async fn check(&self, owner: impl AsRef<str>, repo: impl AsRef<str>) -> Result<bool> {
let route = format!("/user/starred/{}/{}", owner.as_ref(), repo.as_ref());
let response = self.crab._get(route).await?;
match response.status() {
http::StatusCode::NO_CONTENT => Ok(true),
http::StatusCode::NOT_FOUND => Ok(false),
_ => Err(crate::map_github_error(response).await.unwrap_err()),
}
}
pub async fn star(&self, owner: impl AsRef<str>, repo: impl AsRef<str>) -> Result<()> {
let route = format!("/user/starred/{}/{}", owner.as_ref(), repo.as_ref());
let response = self.crab._put(route, None::<&()>).await?;
if !response.status().is_success() {
return Err(crate::map_github_error(response).await.unwrap_err());
}
Ok(())
}
pub async fn unstar(&self, owner: impl AsRef<str>, repo: impl AsRef<str>) -> Result<()> {
let route = format!("/user/starred/{}/{}", owner.as_ref(), repo.as_ref());
let response = self.crab._delete(route, None::<&()>).await?;
if !response.status().is_success() {
return Err(crate::map_github_error(response).await.unwrap_err());
}
Ok(())
}
}
#[derive(Serialize)]
pub struct ListReposStarredByUserBuilder<'octo> {
#[serde(skip)]
crab: &'octo Octocrab,
#[serde(skip_serializing_if = "Option::is_none")]
direction: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
sort: Option<String>,
#[serde(skip)]
route: String,
}
impl<'octo> ListReposStarredByUserBuilder<'octo> {
pub fn new(crab: &'octo Octocrab, username: impl Into<String>) -> Self {
Self::with_route(
crab,
format!("/users/{username}/starred", username = username.into()),
)
}
pub(crate) fn with_route(crab: &'octo Octocrab, route: impl Into<String>) -> Self {
Self {
crab,
direction: None,
page: None,
per_page: None,
sort: None,
route: route.into(),
}
}
pub fn direction(mut self, direction: impl Into<String>) -> Self {
self.direction = Some(direction.into());
self
}
pub fn page(mut self, page: impl Into<u8>) -> Self {
self.page = Some(page.into());
self
}
pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
self.per_page = Some(per_page.into());
self
}
pub async fn send(self) -> Result<Page<StarredRepository>> {
let mut headers = HeaderMap::new();
headers.insert(
ACCEPT,
"application/vnd.github.star+json"
.parse()
.expect("valid header value"),
);
self.crab
.get_with_headers(&self.route, Some(&self), Some(headers))
.await
}
pub fn sort(mut self, sort: impl Into<String>) -> Self {
self.sort = Some(sort.into());
self
}
}