Refactor: Make sure 'static Future is returned

To make it easier to create generic function

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2024-05-27 23:37:01 +10:00
parent c36145f2b4
commit cb418fda11
No known key found for this signature in database
GPG key ID: 76D1E687CA3C4928
3 changed files with 51 additions and 32 deletions

View file

@ -61,29 +61,43 @@ fn check_http_status_and_header(status: StatusCode, headers: &HeaderMap) -> Resu
} }
} }
fn get_api_endpoint() -> &'static Url {
static API_ENDPOINT: OnceLock<Url> = OnceLock::new();
API_ENDPOINT.get_or_init(|| {
Url::parse("https://api.github.com/").expect("Literal provided must be a valid url")
})
}
pub(super) fn issue_restful_api<T>( pub(super) fn issue_restful_api<T>(
client: &remote::Client, client: &remote::Client,
path: String, path: &[&str],
auth_token: Option<&str>, auth_token: Option<&str>,
) -> impl Future<Output = Result<T, GhApiError>> + Send + Sync + 'static ) -> impl Future<Output = Result<T, GhApiError>> + Send + Sync + 'static
where where
T: DeserializeOwned, T: DeserializeOwned,
{ {
let res = Url::parse(&format!("https://api.github.com/{path}")).map(|url| { let mut url = get_api_endpoint().clone();
let mut request_builder = client
.get(url)
.header("Accept", "application/vnd.github+json")
.header("X-GitHub-Api-Version", "2022-11-28");
if let Some(auth_token) = auth_token { url.path_segments_mut()
request_builder = request_builder.bearer_auth(&auth_token); .expect("get_api_endpoint() should return a https url")
} .extend(path);
request_builder.send(false) debug!("Getting restful API: {url}");
});
let mut request_builder = client
.get(url)
.header("Accept", "application/vnd.github+json")
.header("X-GitHub-Api-Version", "2022-11-28");
if let Some(auth_token) = auth_token {
request_builder = request_builder.bearer_auth(&auth_token);
}
let future = request_builder.send(false);
async move { async move {
let response = res?.await?; let response = future.await?;
check_http_status_and_header(response.status(), response.headers())?; check_http_status_and_header(response.status(), response.headers())?;
@ -105,12 +119,15 @@ struct GraphQLQuery {
query: String, query: String,
} }
fn get_graphql_endpoint() -> &'static Url { fn get_graphql_endpoint() -> Url {
static GRAPHQL_ENDPOINT: OnceLock<Url> = OnceLock::new(); let mut graphql_endpoint = get_api_endpoint().clone();
GRAPHQL_ENDPOINT.get_or_init(|| { graphql_endpoint
Url::parse("https://api.github.com/graphql").expect("Literal provided must be a valid url") .path_segments_mut()
}) .expect("get_api_endpoint() should return a https url")
.push("graphql");
graphql_endpoint
} }
pub(super) fn issue_graphql_query<T>( pub(super) fn issue_graphql_query<T>(
@ -121,15 +138,15 @@ pub(super) fn issue_graphql_query<T>(
where where
T: DeserializeOwned, T: DeserializeOwned,
{ {
let graphql_endpoint = get_graphql_endpoint();
let res = to_json_string(&GraphQLQuery { query }) let res = to_json_string(&GraphQLQuery { query })
.map_err(remote::Error::from) .map_err(remote::Error::from)
.map(|graphql_query| { .map(|graphql_query| {
let graphql_endpoint = get_graphql_endpoint();
debug!("Sending graphql query to {graphql_endpoint}: '{graphql_query}'"); debug!("Sending graphql query to {graphql_endpoint}: '{graphql_query}'");
let request_builder = client let request_builder = client
.post(graphql_endpoint.clone(), graphql_query) .post(graphql_endpoint, graphql_query)
.header("Accept", "application/vnd.github+json") .header("Accept", "application/vnd.github+json")
.bearer_auth(&auth_token); .bearer_auth(&auth_token);

View file

@ -76,12 +76,14 @@ fn fetch_release_artifacts_restful_api(
) -> impl Future<Output = Result<Artifacts, GhApiError>> + Send + Sync + 'static { ) -> impl Future<Output = Result<Artifacts, GhApiError>> + Send + Sync + 'static {
issue_restful_api( issue_restful_api(
client, client,
format!( &[
"repos/{owner}/{repo}/releases/tags/{tag}", "repos",
owner = percent_encode_http_url_path(owner), &percent_encode_http_url_path(owner).to_compact_string(),
repo = percent_encode_http_url_path(repo), &percent_encode_http_url_path(repo).to_compact_string(),
tag = percent_encode_http_url_path(tag), "releases",
), "tags",
&percent_encode_http_url_path(tag).to_compact_string(),
],
auth_token, auth_token,
) )
} }

View file

@ -1,4 +1,4 @@
use compact_str::CompactString; use compact_str::{CompactString, ToCompactString};
use serde::Deserialize; use serde::Deserialize;
use super::{ use super::{
@ -38,11 +38,11 @@ async fn fetch_repo_info_restful_api(
) -> Result<RepoInfo, GhApiError> { ) -> Result<RepoInfo, GhApiError> {
issue_restful_api( issue_restful_api(
client, client,
format!( &[
"repos/{owner}/{repo}", "repos",
owner = percent_encode_http_url_path(owner), &percent_encode_http_url_path(owner).to_compact_string(),
repo = percent_encode_http_url_path(repo), &percent_encode_http_url_path(repo).to_compact_string(),
), ],
auth_token, auth_token,
) )
.await .await