wip: connect to github

This commit is contained in:
2026-04-24 19:22:25 +01:00
parent b327648d31
commit a9f4d1d923
11 changed files with 587 additions and 146 deletions

View File

@@ -1,3 +1,8 @@
use std::fmt::format;
use reqwest::{Response, dns::Resolving};
use serde::Deserialize;
use crate::query;
pub(crate) mod auth;
@@ -7,27 +12,56 @@ pub(crate) mod user;
#[derive(Clone)]
pub struct QueryContext {
pub(crate) http: reqwest::Client,
pub(crate) auth: Option<Auth>,
pub(crate) auth: Option<AuthTokens>,
pub(crate) github: GithubCredentials,
}
#[derive(Clone)]
pub(crate) struct Auth {
pub(crate) access_token: &'static str,
pub(crate) refresh_token: &'static str,
pub(crate) struct AuthTokens {
pub(crate) access_token: String,
}
#[derive(Clone)]
pub(crate) struct GithubCredentials {
pub(crate) base_url: &'static str,
pub(crate) client_id: &'static str,
}
pub enum Error {
#[derive(Debug)]
pub(crate) enum Error {
Unauthenticated,
Github(GithubError),
MalformedResponse(serde_json::Error),
HttpError(reqwest::Error),
}
#[derive(Debug, Deserialize)]
pub(crate) struct GithubError {
pub error: String,
pub error_description: Option<String>,
pub error_uri: Option<String>,
}
impl QueryContext {
fn auth(&self) -> Result<&AuthTokens, Error> {
self.auth.as_ref().ok_or(Error::Unauthenticated)
}
fn github_request(
&self,
method: reqwest::Method,
url: &str,
) -> Result<reqwest::RequestBuilder, Error> {
let auth = self.auth()?;
Ok(self
.http
.request(method, format!("{}{}", self.github.base_url, url))
.header("Accept", "application/vnd.github+json")
.header("X-GitHub-Api-Version", "2026-03-10")
.bearer_auth(&auth.access_token))
}
}
impl query::Context for QueryContext {}
impl From<reqwest::Error> for Error {
@@ -41,3 +75,19 @@ impl From<serde_json::Error> for Error {
Self::MalformedResponse(value)
}
}
async fn parse_response<T>(res: reqwest::Response) -> Result<T, Error>
where
T: serde::de::DeserializeOwned,
{
let status = res.status().clone();
let data = res.bytes().await?;
if status.is_success() {
serde_json::from_slice::<T>(&data).map_err(|e| e.into())
} else {
serde_json::from_slice::<GithubError>(&data)
.map_err(|e| e.into())
.and_then(|e| Err(Error::Github(e)))
}
}