Rework query infrastructure

This commit is contained in:
Kiana Sheibani 2023-08-27 16:18:03 -04:00
parent 7751829bd5
commit 589277bb34
Signed by: toki
GPG key ID: 6CB106C25E86A9F7
3 changed files with 27 additions and 18 deletions

View file

@ -41,7 +41,7 @@ fn main() {
.expect("Error reading from stdin"); .expect("Error reading from stdin");
if let Some(response) = block_on(run_query::<VideogameSearch, _>( if let Some(response) = block_on(run_query::<VideogameSearch, _>(
VideogameSearchVars { name: search }, VideogameSearchVars { name: &search },
&auth_key, &auth_key,
)) { )) {
for game in response.into_iter() { for game in response.into_iter() {

View file

@ -1,5 +1,3 @@
use std::fmt::{Display, Formatter};
use cynic::{GraphQlResponse, QueryBuilder}; use cynic::{GraphQlResponse, QueryBuilder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -19,18 +17,24 @@ pub struct ID(pub u64);
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VideogameId(pub u64); pub struct VideogameId(pub u64);
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct PlayerId(pub u64); pub struct EntrantId(pub u64);
// Query machinery // Query machinery
pub trait QueryUnwrap<Vars>: QueryBuilder<Vars> { pub trait QueryUnwrap<Vars>: QueryBuilder<Vars> {
type VarsUnwrapped;
type Unwrapped; type Unwrapped;
fn wrap_vars(vars: Self::VarsUnwrapped) -> Vars;
fn unwrap_response(response: GraphQlResponse<Self>) -> Option<Self::Unwrapped>; fn unwrap_response(response: GraphQlResponse<Self>) -> Option<Self::Unwrapped>;
} }
// Generic function for running start.gg queries // Generic function for running start.gg queries
pub async fn run_query<Builder: 'static, Vars>(vars: Vars, auth: &str) -> Option<Builder::Unwrapped> pub async fn run_query<Builder: 'static, Vars>(
vars: Builder::VarsUnwrapped,
auth: &str,
) -> Option<Builder::Unwrapped>
where where
Builder: QueryUnwrap<Vars>, Builder: QueryUnwrap<Vars>,
Vars: Serialize, Vars: Serialize,
@ -38,7 +42,7 @@ where
{ {
use cynic::http::SurfExt; use cynic::http::SurfExt;
let query = Builder::build(vars); let query = Builder::build(<Builder as QueryUnwrap<Vars>>::wrap_vars(vars));
let response = surf::post("https://api.start.gg/gql/alpha") let response = surf::post("https://api.start.gg/gql/alpha")
.header("Authorization", String::from("Bearer ") + auth) .header("Authorization", String::from("Bearer ") + auth)

View file

@ -2,11 +2,11 @@ use super::{QueryUnwrap, VideogameId, ID};
use cynic::GraphQlResponse; use cynic::GraphQlResponse;
use schema::schema; use schema::schema;
// Query // Variables
#[derive(cynic::QueryVariables)] #[derive(cynic::QueryVariables)]
pub struct VideogameSearchVars { pub struct VideogameSearchVars<'a> {
pub name: String, pub name: &'a str,
} }
// Query // Query
@ -15,18 +15,18 @@ pub struct VideogameSearchVars {
#[cynic(graphql_type = "Query", variables = "VideogameSearchVars")] #[cynic(graphql_type = "Query", variables = "VideogameSearchVars")]
pub struct VideogameSearch { pub struct VideogameSearch {
#[arguments(query: { filter: { name: $name }, page: 1, perPage: 10 })] #[arguments(query: { filter: { name: $name }, page: 1, perPage: 10 })]
pub videogames: Option<VideogameConnection>, videogames: Option<VideogameConnection>,
} }
#[derive(cynic::QueryFragment, Debug)] #[derive(cynic::QueryFragment, Debug)]
pub struct VideogameConnection { struct VideogameConnection {
pub nodes: Option<Vec<Option<Videogame>>>, nodes: Option<Vec<Option<Videogame>>>,
} }
#[derive(cynic::QueryFragment, Debug)] #[derive(cynic::QueryFragment, Debug)]
pub struct Videogame { struct Videogame {
pub id: Option<ID>, id: Option<ID>,
pub name: Option<String>, name: Option<String>,
} }
// Unwrapping // Unwrapping
@ -36,9 +36,14 @@ pub struct VideogameResponse {
pub name: String, pub name: String,
} }
impl QueryUnwrap<VideogameSearchVars> for VideogameSearch { impl<'a> QueryUnwrap<VideogameSearchVars<'a>> for VideogameSearch {
type VarsUnwrapped = VideogameSearchVars<'a>;
type Unwrapped = Vec<VideogameResponse>; type Unwrapped = Vec<VideogameResponse>;
fn wrap_vars(vars: VideogameSearchVars) -> VideogameSearchVars {
vars
}
fn unwrap_response( fn unwrap_response(
response: GraphQlResponse<VideogameSearch>, response: GraphQlResponse<VideogameSearch>,
) -> Option<Vec<VideogameResponse>> { ) -> Option<Vec<VideogameResponse>> {
@ -48,14 +53,14 @@ impl QueryUnwrap<VideogameSearchVars> for VideogameSearch {
.videogames? .videogames?
.nodes? .nodes?
.into_iter() .into_iter()
.map(|game| { .filter_map(|game| {
let game_ = game?; let game_ = game?;
Some(VideogameResponse { Some(VideogameResponse {
id: VideogameId(game_.id?.0), id: VideogameId(game_.id?.0),
name: game_.name?, name: game_.name?,
}) })
}) })
.try_collect()?, .collect(),
) )
} }
} }