wip: connect to github
This commit is contained in:
60
src/api.rs
60
src/api.rs
@@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user