242 lines
6.0 KiB
Rust
242 lines
6.0 KiB
Rust
use reqwest::header;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::result::Result as StdResult;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum Error {
|
|
#[error("error from reqwest: {0:#?}")]
|
|
Reqwest(#[from] reqwest::Error),
|
|
|
|
#[error("bad API token: {0:#?}")]
|
|
BadAPIToken(#[from] reqwest::header::InvalidHeaderValue),
|
|
|
|
#[error("error parsing/serializing json: {0:#?}")]
|
|
Json(#[from] serde_json::Error),
|
|
|
|
#[error("tag not found: {0}")]
|
|
TagNotFound(String),
|
|
}
|
|
|
|
pub type Result<T> = StdResult<T, Error>;
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Author {
|
|
pub id: i64,
|
|
pub login: String,
|
|
pub full_name: String,
|
|
pub email: String,
|
|
pub avatar_url: String,
|
|
pub language: String,
|
|
pub is_admin: bool,
|
|
pub last_login: String,
|
|
pub created: String,
|
|
pub username: String,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Release {
|
|
pub id: i64,
|
|
pub tag_name: String,
|
|
pub target_commitish: String,
|
|
pub name: String,
|
|
pub body: String,
|
|
pub url: String,
|
|
pub tarball_url: String,
|
|
pub zipball_url: String,
|
|
pub draft: bool,
|
|
pub prerelease: bool,
|
|
pub created_at: String,
|
|
pub published_at: String,
|
|
pub author: Author,
|
|
pub assets: Vec<Attachment>,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct CreateRelease {
|
|
pub body: String,
|
|
pub draft: bool,
|
|
pub name: String,
|
|
pub prerelease: bool,
|
|
pub tag_name: String,
|
|
pub target_commitish: String,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Attachment {
|
|
pub id: i64,
|
|
pub name: String,
|
|
pub size: i64,
|
|
pub download_count: i64,
|
|
pub created_at: String,
|
|
pub uuid: String,
|
|
pub browser_download_url: String,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Repo {
|
|
pub allow_merge_commits: bool,
|
|
pub allow_rebase: bool,
|
|
pub allow_rebase_explicit: bool,
|
|
pub allow_squash_merge: bool,
|
|
pub archived: bool,
|
|
pub avatar_url: String,
|
|
pub clone_url: String,
|
|
pub created_at: String,
|
|
pub default_branch: String,
|
|
pub description: String,
|
|
pub empty: bool,
|
|
pub fork: bool,
|
|
pub forks_count: i64,
|
|
pub full_name: String,
|
|
pub has_issues: bool,
|
|
pub has_pull_requests: bool,
|
|
pub has_wiki: bool,
|
|
pub html_url: String,
|
|
pub id: i64,
|
|
pub ignore_whitespace_conflicts: bool,
|
|
pub mirror: bool,
|
|
pub name: String,
|
|
pub open_issues_count: i64,
|
|
pub open_pr_counter: i64,
|
|
pub original_url: String,
|
|
pub owner: User,
|
|
pub permissions: Permissions,
|
|
pub private: bool,
|
|
pub release_counter: i64,
|
|
pub size: i64,
|
|
pub ssh_url: String,
|
|
pub stars_count: i64,
|
|
pub template: bool,
|
|
pub updated_at: String,
|
|
pub watchers_count: i64,
|
|
pub website: String,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct User {
|
|
pub avatar_url: String,
|
|
pub created: String,
|
|
pub email: String,
|
|
pub full_name: String,
|
|
pub id: i64,
|
|
pub is_admin: bool,
|
|
pub language: String,
|
|
pub last_login: String,
|
|
pub login: String,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Permissions {
|
|
pub admin: bool,
|
|
pub pull: bool,
|
|
pub push: bool,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Version {
|
|
pub version: String,
|
|
}
|
|
|
|
pub struct Client {
|
|
cli: reqwest::Client,
|
|
base_url: String,
|
|
}
|
|
|
|
impl Client {
|
|
pub fn new(base_url: String, token: String, user_agent: String) -> Result<Self> {
|
|
let mut headers = header::HeaderMap::new();
|
|
let auth = format!("token {}", token);
|
|
let auth = auth.as_str();
|
|
headers.insert(header::AUTHORIZATION, header::HeaderValue::from_str(auth)?);
|
|
let cli = reqwest::Client::builder()
|
|
.user_agent(user_agent)
|
|
.default_headers(headers)
|
|
.build()?;
|
|
Ok(Self {
|
|
cli: cli,
|
|
base_url: base_url,
|
|
})
|
|
}
|
|
|
|
pub async fn version(&self) -> Result<Version> {
|
|
Ok(self
|
|
.cli
|
|
.get(&format!("{}/api/v1/version", self.base_url))
|
|
.send()
|
|
.await?
|
|
.error_for_status()?
|
|
.json()
|
|
.await?)
|
|
}
|
|
|
|
pub async fn get_release_by_tag(
|
|
&self,
|
|
owner: String,
|
|
repo: String,
|
|
tag: String,
|
|
) -> Result<Release> {
|
|
let releases: Vec<Release> = self.get_releases(owner, repo).await?;
|
|
let mut release: Option<Release> = None;
|
|
|
|
for rls in releases {
|
|
if *tag == rls.tag_name {
|
|
release = Some(rls);
|
|
}
|
|
}
|
|
|
|
match release {
|
|
None => Err(Error::TagNotFound(tag)),
|
|
Some(release) => Ok(release),
|
|
}
|
|
}
|
|
|
|
pub async fn get_repo(&self, owner: String, repo: String) -> Result<Repo> {
|
|
Ok(self
|
|
.cli
|
|
.get(&format!(
|
|
"{}/api/v1/repos/{}/{}",
|
|
self.base_url, owner, repo
|
|
))
|
|
.send()
|
|
.await?
|
|
.error_for_status()?
|
|
.json()
|
|
.await?)
|
|
}
|
|
|
|
pub async fn get_releases(&self, owner: String, repo: String) -> Result<Vec<Release>> {
|
|
Ok(self
|
|
.cli
|
|
.get(&format!(
|
|
"{}/api/v1/repos/{}/{}/releases",
|
|
self.base_url, owner, repo
|
|
))
|
|
.send()
|
|
.await?
|
|
.error_for_status()?
|
|
.json()
|
|
.await?)
|
|
}
|
|
|
|
pub async fn create_release(
|
|
&self,
|
|
owner: String,
|
|
repo: String,
|
|
cr: CreateRelease,
|
|
) -> Result<Release> {
|
|
Ok(self
|
|
.cli
|
|
.post(&format!(
|
|
"{}/api/v1/repos/{}/{}/releases",
|
|
self.base_url, owner, repo
|
|
))
|
|
.json(&cr)
|
|
.send()
|
|
.await?
|
|
.error_for_status()?
|
|
.json()
|
|
.await?)
|
|
}
|
|
}
|