gitea_pages/frontend/src/graphql.rs

100 lines
3.2 KiB
Rust

use lazy_static::lazy_static;
use serde::Deserialize;
use std::future::Future;
use std::pin::Pin;
use crate::stores;
lazy_static! {
pub static ref URL: String = format!(
"{}/graphql",
web_sys::window().unwrap().location().origin().unwrap()
);
}
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
pub trait ReqwestExt {
fn run_graphql<ResponseData, Vars, Extensions>(
self,
operation: cynic::Operation<ResponseData, Vars>,
) -> BoxFuture<
'static,
Result<cynic::GraphQlResponse<ResponseData, Extensions>, cynic::http::CynicReqwestError>,
>
where
Vars: serde::Serialize,
ResponseData: serde::de::DeserializeOwned + 'static,
Extensions: serde::de::DeserializeOwned + 'static;
}
impl ReqwestExt for reqwest::RequestBuilder {
fn run_graphql<ResponseData, Vars, Extensions>(
self,
operation: cynic::Operation<ResponseData, Vars>,
) -> BoxFuture<
'static,
Result<cynic::GraphQlResponse<ResponseData, Extensions>, cynic::http::CynicReqwestError>,
>
where
Vars: serde::Serialize,
ResponseData: serde::de::DeserializeOwned + 'static,
Extensions: serde::de::DeserializeOwned + 'static,
{
let builder = self.json(&operation);
Box::pin(async move {
match builder.send().await {
Ok(response) => {
let status = response.status();
if !status.is_success() {
let body_string = response.text().await?;
match serde_json::from_str::<cynic::GraphQlResponse<ResponseData, Extensions>>(
&body_string,
) {
Ok(response) => return Ok(response),
Err(_) => {
return Err(cynic::http::CynicReqwestError::ErrorResponse(
status,
body_string,
));
}
};
}
response
.json::<cynic::GraphQlResponse<ResponseData, Extensions>>()
.await
.map_err(cynic::http::CynicReqwestError::ReqwestError)
}
Err(e) => Err(cynic::http::CynicReqwestError::ReqwestError(e)),
}
})
}
}
pub fn client(user: Option<&stores::UserData>) -> reqwest::RequestBuilder {
let client = reqwest::Client::new().post(URL.as_str());
if let Some(x) = user {
client.basic_auth(&x.username, Some(&x.password))
} else {
client
}
}
#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct ErrorExtensions {
#[serde(rename = "type")]
pub error_type: String,
}
pub type GraphQLError = cynic::GraphQlError<ErrorExtensions>;
pub type GraphQLResponse<T> = cynic::GraphQlResponse<T, ErrorExtensions>;
pub type GraphQLResult<T> = Result<GraphQLResponse<T>, cynic::http::CynicReqwestError>;
include!(concat!(env!("OUT_DIR"), "/graphql.rs"));
pub struct Uuid(pub String);
cynic::impl_scalar!(Uuid, schema::UUID);