generated from pure_sagacity/rust-starter
378c1f7c0d
cursor.
95 lines
2.5 KiB
Rust
95 lines
2.5 KiB
Rust
use super::Repository;
|
|
use serde::Deserialize;
|
|
|
|
use crate::providers::Provider;
|
|
|
|
pub struct Github {
|
|
pub username: String,
|
|
pub token: Option<String>,
|
|
}
|
|
|
|
impl Github {
|
|
pub fn new(username: String, token: Option<String>) -> Self {
|
|
Self { username, token }
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct GithubRepoDto {
|
|
id: u64,
|
|
name: String,
|
|
owner: GithubOwnerDto,
|
|
ssh_url: Option<String>,
|
|
clone_url: String,
|
|
stargazers_count: u64,
|
|
description: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct GithubOwnerDto {
|
|
login: String,
|
|
}
|
|
|
|
impl From<GithubRepoDto> for Repository {
|
|
fn from(gh: GithubRepoDto) -> Self {
|
|
Repository {
|
|
id: gh.id,
|
|
name: gh.name,
|
|
owner: gh.owner.login,
|
|
ssh_url: gh.ssh_url,
|
|
https_url: gh.clone_url,
|
|
stars: gh.stargazers_count,
|
|
description: gh.description,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Provider for Github {
|
|
async fn repositories(&self) -> super::Result<Vec<Repository>> {
|
|
let client = reqwest::Client::new();
|
|
let mut page = 1;
|
|
let mut repos: Vec<Repository> = Vec::new();
|
|
|
|
let base_url = match self.token.is_some() {
|
|
true => "https://api.github.com/user/repos".to_string(),
|
|
false => format!("https://api.github.com/users/{}/repos", self.username),
|
|
};
|
|
|
|
loop {
|
|
let url = format!("{}?per_page=100&page={}", base_url, page);
|
|
|
|
let mut request = client
|
|
.get(&url)
|
|
.header("User-Agent", "my-app")
|
|
.header("Accept", "application/vnd.github+json"); // Best practice for GitHub API
|
|
|
|
// Apply token authentication if it's available
|
|
if let Some(ref token) = self.token {
|
|
request = request.bearer_auth(token);
|
|
}
|
|
|
|
let response = request.send().await?;
|
|
let status = response.status();
|
|
|
|
if !status.is_success() {
|
|
let error_text = response.text().await?;
|
|
let err = format!("Github API Error ({}): {}", status, error_text);
|
|
return Err(err.into());
|
|
}
|
|
|
|
let gh_page: Vec<GithubRepoDto> = response.json().await?;
|
|
|
|
if gh_page.is_empty() {
|
|
break;
|
|
}
|
|
|
|
let domain_repos = gh_page.into_iter().map(Repository::from);
|
|
repos.extend(domain_repos);
|
|
|
|
page += 1;
|
|
}
|
|
|
|
Ok(repos)
|
|
}
|
|
}
|