StartRNR/cli/src/queries.rs

90 lines
2.4 KiB
Rust
Raw Normal View History

use cynic::{GraphQlResponse, QueryBuilder};
use serde::{Deserialize, Serialize};
2023-09-02 01:47:52 -04:00
use std::path::Path;
2023-08-26 23:48:13 -04:00
2023-08-27 03:02:18 -04:00
pub mod search_games;
2023-08-28 00:57:20 -04:00
pub use search_games::*;
2023-08-27 16:18:22 -04:00
pub mod tournament_sets;
2023-08-28 00:57:20 -04:00
pub use tournament_sets::*;
2023-09-02 20:46:23 -04:00
pub mod player_info;
pub use player_info::*;
2023-08-27 03:11:23 -04:00
use schema::schema;
2023-09-02 01:47:52 -04:00
// Auth key
pub fn get_auth_key(config_dir: &Path) -> Option<String> {
use std::env::{var, VarError};
use std::fs::read_to_string;
match var("AUTH_KEY") {
Ok(key) => Some(key),
Err(VarError::NotUnicode(_)) => panic!("Invalid authorization key"),
Err(VarError::NotPresent) => {
let mut auth_file = config_dir.to_owned();
auth_file.push("auth.txt");
read_to_string(auth_file).ok().and_then(|s| {
let trimmed = s.trim();
if trimmed.is_empty() {
None
} else {
Some(trimmed.to_owned())
}
})
}
}
}
2023-09-02 19:48:47 -04:00
// Types
// HACK: Unfortunately, start.gg seems to use integers for its ID type, whereas
// cynic always assumes that IDs are strings. To get around that, we define new
// scalar types that deserialize to u64.
#[derive(cynic::Scalar, Debug, Copy, Clone)]
#[cynic(graphql_type = "ID")]
pub struct VideogameId(pub u64);
#[derive(cynic::Scalar, Debug, Copy, Clone)]
#[cynic(graphql_type = "ID")]
pub struct EntrantId(pub u64);
#[derive(cynic::Scalar, Debug, Copy, Clone)]
#[cynic(graphql_type = "ID")]
pub struct PlayerId(pub u64);
#[derive(cynic::Scalar, Debug, Clone)]
pub struct Timestamp(pub u64);
2023-08-27 05:33:03 -04:00
// Query machinery
2023-08-27 03:52:38 -04:00
2023-08-27 16:44:18 -04:00
pub trait QueryUnwrap<Vars>: 'static + QueryBuilder<Vars> {
2023-08-27 16:18:03 -04:00
type VarsUnwrapped;
type Unwrapped;
2023-08-27 03:52:38 -04:00
2023-08-27 16:18:03 -04:00
fn wrap_vars(vars: Self::VarsUnwrapped) -> Vars;
fn unwrap_response(response: GraphQlResponse<Self>) -> Option<Self::Unwrapped>;
}
2023-08-27 03:52:38 -04:00
// Generic function for running start.gg queries
pub fn run_query<Builder, Vars>(
2023-08-27 16:18:03 -04:00
vars: Builder::VarsUnwrapped,
auth: &str,
) -> Option<Builder::Unwrapped>
where
Builder: QueryUnwrap<Vars>,
Vars: Serialize,
for<'de> Builder: Deserialize<'de>,
2023-08-27 03:52:38 -04:00
{
use cynic::http::ReqwestBlockingExt;
2023-08-27 03:52:38 -04:00
2023-08-27 16:44:18 -04:00
let query = Builder::build(Builder::wrap_vars(vars));
2023-08-27 03:52:38 -04:00
let response = reqwest::blocking::Client::new()
.post("https://api.start.gg/gql/alpha")
2023-08-27 03:52:38 -04:00
.header("Authorization", String::from("Bearer ") + auth)
.run_graphql(query);
2023-08-27 03:52:38 -04:00
2023-08-27 16:44:18 -04:00
Builder::unwrap_response(response.unwrap())
2023-08-27 03:52:38 -04:00
}