generated from pure_sagacity/rust-starter
added credential management to keyring.
cursor.
This commit is contained in:
+19
-16
@@ -3,26 +3,24 @@ use serde::Deserialize;
|
||||
|
||||
use crate::providers::Provider;
|
||||
|
||||
// TODO: add email and password authentication for viewing private repos.
|
||||
pub struct Github {
|
||||
pub username: String,
|
||||
pub token: Option<String>,
|
||||
}
|
||||
|
||||
impl Github {
|
||||
fn new(username: String) -> Self {
|
||||
Self { username }
|
||||
pub fn new(username: String, token: Option<String>) -> Self {
|
||||
Self { username, token }
|
||||
}
|
||||
}
|
||||
|
||||
// 1. This struct matches GitHub's exact API shape.
|
||||
// It remains completely hidden inside your GitHub provider module.
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct GithubRepoDto {
|
||||
id: u64,
|
||||
name: String,
|
||||
owner: GithubOwnerDto,
|
||||
ssh_url: Option<String>,
|
||||
clone_url: String, // Or html_url
|
||||
clone_url: String,
|
||||
stargazers_count: u64,
|
||||
description: Option<String>,
|
||||
}
|
||||
@@ -32,7 +30,6 @@ struct GithubOwnerDto {
|
||||
login: String,
|
||||
}
|
||||
|
||||
// 2. Map the GitHub DTO to your general Repository struct
|
||||
impl From<GithubRepoDto> for Repository {
|
||||
fn from(gh: GithubRepoDto) -> Self {
|
||||
Repository {
|
||||
@@ -53,18 +50,25 @@ impl Provider for Github {
|
||||
let mut page = 1;
|
||||
let mut repos: Vec<Repository> = Vec::new();
|
||||
|
||||
loop {
|
||||
let url = format!(
|
||||
"https://api.github.com/users/{}/repos?per_page=100&page={}",
|
||||
&self.username, page
|
||||
);
|
||||
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),
|
||||
};
|
||||
|
||||
let response = client
|
||||
loop {
|
||||
let url = format!("{}?per_page=100&page={}", base_url, page);
|
||||
|
||||
let mut request = client
|
||||
.get(&url)
|
||||
.header("User-Agent", "my-app")
|
||||
.send()
|
||||
.await?;
|
||||
.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() {
|
||||
@@ -79,7 +83,6 @@ impl Provider for Github {
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert the GitHub DTOs seamlessly into your clean domain structs
|
||||
let domain_repos = gh_page.into_iter().map(Repository::from);
|
||||
repos.extend(domain_repos);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user