mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-05-04 10:03:48 +01:00
146 lines
2.9 KiB
Rust
146 lines
2.9 KiB
Rust
use std::{collections::HashMap, str::FromStr, time::Duration};
|
|
|
|
use anyhow::Result;
|
|
use serde::{de::DeserializeOwned, Deserialize};
|
|
use ureq::Response;
|
|
use url::Url;
|
|
|
|
use crate::types::LuneReleaseData;
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct GitHub {
|
|
fetcher: Fetcher,
|
|
repository: Repository,
|
|
}
|
|
|
|
impl GitHub {
|
|
pub fn new(repo: (&str, &str)) -> Self {
|
|
let fetcher = Fetcher::new();
|
|
|
|
Self {
|
|
fetcher: fetcher.to_owned(),
|
|
repository: Repository::new(repo.0, repo.1, fetcher),
|
|
}
|
|
}
|
|
|
|
pub fn fetch_releases(&self) -> Result<LuneReleaseData> {
|
|
let api_uri = Url::from_str(self.repository.api_url().as_str())?.join("releases/")?.join("latest")?;
|
|
|
|
Ok(match self.fetcher.fetch::<_, LuneReleaseData>(Method::Get, api_uri, true)? {
|
|
FetchResult::Result(res) => res,
|
|
FetchResult::Response(_) => {
|
|
unreachable!("Fetcher returned Response instead of Result")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct Repository {
|
|
fetcher: Fetcher,
|
|
scope: String,
|
|
repo: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct RepositoryMeta {
|
|
pub full_name: String,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub license: HashMap<String, String>,
|
|
pub topics: Vec<String>,
|
|
pub forks: u32,
|
|
pub open_issues: u32,
|
|
pub stars: u32,
|
|
}
|
|
|
|
impl Repository {
|
|
pub fn new<T>(scope: T, repo: T, fetcher: Fetcher) -> Self
|
|
where
|
|
T: ToString,
|
|
{
|
|
Self {
|
|
fetcher,
|
|
scope: scope.to_string(),
|
|
repo: repo.to_string(),
|
|
}
|
|
}
|
|
|
|
pub fn scope(&self) -> &String {
|
|
&self.scope
|
|
}
|
|
|
|
pub fn repo(&self) -> &String {
|
|
&self.repo
|
|
}
|
|
|
|
pub fn api_url(&self) -> String {
|
|
format!("https://api.github.com/repos/{}/{}/", self.scope, self.repo)
|
|
}
|
|
|
|
pub fn fetch_meta(&self) -> Result<RepositoryMeta> {
|
|
Ok(
|
|
match self
|
|
.fetcher
|
|
.fetch::<_, RepositoryMeta>(Method::Get, Url::from_str(self.api_url().as_str())?, true)?
|
|
{
|
|
FetchResult::Result(deserialized) => deserialized,
|
|
FetchResult::Response(_) => {
|
|
unreachable!("Fetcher returned Response instead of Result")
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Fetcher {
|
|
client: ureq::Agent,
|
|
}
|
|
|
|
pub enum Method {
|
|
Get,
|
|
Post,
|
|
}
|
|
|
|
pub enum FetchResult<D> {
|
|
Result(D),
|
|
Response(Box<Response>),
|
|
}
|
|
|
|
impl Default for Fetcher {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Fetcher {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
client: ureq::builder()
|
|
.redirects(2)
|
|
.https_only(true)
|
|
.timeout(Duration::from_secs(30))
|
|
.user_agent("lune-action/0.1.0")
|
|
.build(),
|
|
}
|
|
}
|
|
|
|
pub fn fetch<U, D>(&self, method: Method, uri: U, to_deserialize: bool) -> Result<FetchResult<D>>
|
|
where
|
|
U: Into<url::Url>,
|
|
D: DeserializeOwned,
|
|
{
|
|
let method = match method {
|
|
Method::Get => "GET",
|
|
Method::Post => "POST",
|
|
};
|
|
|
|
let req = self.client.request_url(method, &uri.into());
|
|
|
|
Ok(match to_deserialize {
|
|
true => FetchResult::Result(serde_json::from_reader::<_, D>(req.call()?.into_reader())?),
|
|
false => FetchResult::Response(Box::new(req.call()?)),
|
|
})
|
|
}
|
|
}
|