use hyper::{Error as HyperError, Url};
use hyper::header::{Accept, ContentLength, qitem};
use hyper::mime::{Mime, TopLevel, SubLevel};
use common::{Repository, User};
use client::Client;
use error;
use utils;
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct ListStarTimeStamp {
pub starred_at: String,
pub user: User
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct ListRepoStarTimeStamp {
pub starred_at: String,
pub repo: Repository
}
pub enum Sort {
Created,
Updated
}
pub enum Direction {
Ascending,
Descending
}
pub trait StarringExt {
fn get_repos_owner_repo_stargazers(&mut self, owner: String, repo: String) -> Result<Vec<User>, error::Error>;
fn get_repos_owner_repo_stargazers_timestamp(&mut self, owner: String, repo: String) -> Result<Vec<ListStarTimeStamp>, error::Error>;
fn get_users_username_starred(&mut self, username: String, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<Repository>, error::Error>;
fn get_users_username_starred_timestamp(&mut self, username: String, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<ListRepoStarTimeStamp>, error::Error>;
fn get_user_starred(&mut self, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<Repository>, error::Error>;
fn get_user_starred_timestamp(&mut self, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<ListRepoStarTimeStamp>, error::Error>;
fn get_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error>;
fn put_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error>;
fn delete_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error>;
}
impl StarringExt for Client {
fn get_repos_owner_repo_stargazers(&mut self, owner: String, repo: String) -> Result<Vec<User>, error::Error> {
utils::request_endpoint(self, format!("/repos/{}/{}/stargazers", owner, repo))
}
fn get_repos_owner_repo_stargazers_timestamp(&mut self, owner: String, repo: String) -> Result<Vec<ListStarTimeStamp>, error::Error> {
let mut header = self.get_default_headers();
header.remove::<Accept>();
header.set(Accept(vec![qitem(Mime(TopLevel::Application, SubLevel::Ext("vnd.github.v3.star+json".to_string()), vec![]))]));
utils::request_endpoint_with_headers(self, format!("/repos/{}/{}/stargazers", owner, repo), Some(header))
}
fn get_users_username_starred(&mut self, username: String, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<Repository>, error::Error> {
let mut url = match Url::parse(&format!("{}/users/{}/starred", self.api_url, username)[..]) {
Ok(url) => url,
Err(err) => return Err(error::Error::HTTP(HyperError::Uri(err)))
};
{
let mut query_pairs = url.query_pairs_mut();
query_pairs.clear();
if let Some(param) = sort {
let sorting = match param {
Sort::Created => "created",
Sort::Updated => "updated",
};
query_pairs.append_pair("sort", &sorting[..]);
}
if let Some(param) = direction {
let dir = match param {
Direction::Ascending => "asc",
Direction::Descending => "desc",
};
query_pairs.append_pair("direction", &dir[..]);
}
}
utils::request_endpoint(self, format!("/users/{}/starred?{}", username, url.query().unwrap()))
}
fn get_user_starred(&mut self, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<Repository>, error::Error> {
let mut url = match Url::parse(&format!("{}/user/starred", self.api_url)[..]) {
Ok(url) => url,
Err(err) => return Err(error::Error::HTTP(HyperError::Uri(err)))
};
{
let mut query_pairs = url.query_pairs_mut();
query_pairs.clear();
if let Some(param) = sort {
let sorting = match param {
Sort::Created => "created",
Sort::Updated => "updated",
};
query_pairs.append_pair("sort", &sorting[..]);
}
if let Some(param) = direction {
let dir = match param {
Direction::Ascending => "asc",
Direction::Descending => "desc",
};
query_pairs.append_pair("direction", &dir[..]);
}
}
utils::request_endpoint(self, format!("/users/starred?{}", url.query().unwrap()))
}
fn get_users_username_starred_timestamp(&mut self, username: String, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<ListRepoStarTimeStamp>, error::Error> {
let mut url = match Url::parse(&format!("{}/users/{}/starred", self.api_url, username)[..]) {
Ok(url) => url,
Err(err) => return Err(error::Error::HTTP(HyperError::Uri(err)))
};
{
let mut query_pairs = url.query_pairs_mut();
query_pairs.clear();
if let Some(param) = sort {
let sorting = match param {
Sort::Created => "created",
Sort::Updated => "updated",
};
query_pairs.append_pair("sort", &sorting[..]);
}
if let Some(param) = direction {
let dir = match param {
Direction::Ascending => "asc",
Direction::Descending => "desc",
};
query_pairs.append_pair("direction", &dir[..]);
}
}
let mut header = self.get_default_headers();
header.remove::<Accept>();
header.set(Accept(vec![qitem(Mime(TopLevel::Application, SubLevel::Ext("vnd.github.v3.star+json".to_string()), vec![]))]));
utils::request_endpoint_with_headers(self, format!("/users/{}/starred?{}", username, url.query().unwrap()), Some(header))
}
fn get_user_starred_timestamp(&mut self, sort: Option<Sort>, direction: Option<Direction>) -> Result<Vec<ListRepoStarTimeStamp>, error::Error> {
let mut url = match Url::parse(&format!("{}/user/starred", self.api_url)[..]) {
Ok(url) => url,
Err(err) => return Err(error::Error::HTTP(HyperError::Uri(err)))
};
{
let mut query_pairs = url.query_pairs_mut();
query_pairs.clear();
if let Some(param) = sort {
let sorting = match param {
Sort::Created => "created",
Sort::Updated => "updated",
};
query_pairs.append_pair("sort", &sorting[..]);
}
if let Some(param) = direction {
let dir = match param {
Direction::Ascending => "asc",
Direction::Descending => "desc",
};
query_pairs.append_pair("direction", &dir[..]);
}
}
let mut header = self.get_default_headers();
header.remove::<Accept>();
header.set(Accept(vec![qitem(Mime(TopLevel::Application, SubLevel::Ext("vnd.github.v3.star+json".to_string()), vec![]))]));
utils::request_endpoint_with_headers(self, format!("/user/starred?{}", url.query().unwrap()), Some(header))
}
fn get_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error> {
utils::request_endpoint(self, format!("/user/starred/{}/{}", owner, repo))
}
fn put_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error> {
let mut header = self.get_default_headers();
header.set(ContentLength(0u64));
match self.get(format!("/user/starred/{}/{}", owner, repo), Some(header)) {
Ok(_) => Ok(()),
Err(err) => Err(err)
}
}
fn delete_user_starred_owner_repo(&mut self, owner: String, repo: String) -> Result<(), error::Error> {
match self.delete(format!("/user/starred/{}/{}", owner, repo), None) {
Ok(_) => Ok(()),
Err(err) => Err(err)
}
}
}