1use graphql_client::GraphQLQuery;
2use reqwest::{
3 header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE},
4 Client, RequestBuilder,
5};
6
7use crate::{config::Config, connect_params::ConnectParams, introspection::IntrospectionResponse};
8
9#[derive(GraphQLQuery)]
10#[graphql(
11 schema_path = "src/graphql/introspection_schema.graphql",
12 query_path = "src/graphql/introspection_query.graphql",
13 responsive_path = "Serialize",
14 variable_derive = "Deserialize"
15)]
16struct IntrospectionQuery;
17
18pub struct Session;
19
20impl Session {
21 pub fn new() -> Self {
22 Self {}
23 }
24
25 pub fn start(&self, _cfg: &Config, conn: &ConnectParams) -> eyre::Result<RequestBuilder> {
26 let client = Client::builder()
27 .user_agent("graphql-rust/0.10.0")
28 .connection_verbose(true)
29 .build()?;
31
32 let req_builder = client
33 .post(conn.url())
34 .headers(construct_headers())
35 .basic_auth::<String, String>(conn.session_token.to_string(), None);
36
37 Ok(req_builder)
38 }
39
40 pub async fn schema(&self, req_builder: RequestBuilder) -> eyre::Result<IntrospectionResponse> {
41 let request_body: graphql_client::QueryBody<()> = graphql_client::QueryBody {
42 variables: (),
43 query: introspection_query::QUERY,
44 operation_name: introspection_query::OPERATION_NAME,
45 };
46
47 let res = req_builder.json(&request_body).send().await?;
48
49 if res.status().is_success() {
50 } else if res.status().is_server_error() {
52 return Err(eyre::anyhow!("server error!"));
53 } else {
54 let status = res.status();
55 let error_message = match res.text().await {
56 Ok(msg) => match serde_json::from_str::<serde_json::Value>(&msg) {
57 Ok(json) => {
58 format!("HTTP {}\n{}", status, serde_json::to_string_pretty(&json)?)
59 }
60 Err(_) => format!("HTTP {}: {}", status, msg),
61 },
62 Err(_) => format!("HTTP {}", status),
63 };
64 return Err(eyre::anyhow!(error_message));
65 }
66
67 let json: IntrospectionResponse = res.json().await?;
68
69 Ok(json)
70 }
71}
72
73fn construct_headers() -> HeaderMap {
74 let mut headers = HeaderMap::new();
75 headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
76 headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
77 headers
78}