-
Notifications
You must be signed in to change notification settings - Fork 11.4k
/
Copy pathresponse.rs
110 lines (95 loc) · 3.42 KB
/
response.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
use super::ClientError;
use async_graphql::{Response, ServerError, Value};
use reqwest::header::{HeaderMap, HeaderName};
use reqwest::Response as ReqwestResponse;
use serde_json::json;
use std::{collections::BTreeMap, net::SocketAddr};
use sui_graphql_rpc_headers::VERSION_HEADER;
#[derive(Debug)]
pub struct GraphqlResponse {
headers: HeaderMap,
remote_address: Option<SocketAddr>,
http_version: reqwest::Version,
status: reqwest::StatusCode,
full_response: Response,
}
impl GraphqlResponse {
pub async fn from_resp(resp: ReqwestResponse) -> Result<Self, ClientError> {
let headers = resp.headers().clone();
let remote_address = resp.remote_addr();
let http_version = resp.version();
let status = resp.status();
let full_response: Response = resp.json().await.map_err(ClientError::InnerClientError)?;
Ok(Self {
headers,
remote_address,
http_version,
status,
full_response,
})
}
pub fn graphql_version(&self) -> Result<String, ClientError> {
Ok(self
.headers
.get(VERSION_HEADER.as_str())
.ok_or(ClientError::ServiceVersionHeaderNotFound)?
.to_str()
.map_err(|e| ClientError::ServiceVersionHeaderValueInvalidString { error: e })?
.to_string())
}
pub fn response_body(&self) -> &Response {
&self.full_response
}
pub fn response_body_json(&self) -> serde_json::Value {
json!(self.full_response)
}
pub fn response_body_json_pretty(&self) -> String {
serde_json::to_string_pretty(&self.full_response).unwrap()
}
pub fn http_status(&self) -> reqwest::StatusCode {
self.status
}
pub fn http_version(&self) -> reqwest::Version {
self.http_version
}
pub fn http_headers(&self) -> HeaderMap {
self.headers.clone()
}
/// Returns the HTTP headers without the `Date` header.
/// The `Date` header is removed because it is not deterministic.
pub fn http_headers_without_date(&self) -> HeaderMap {
let mut headers = self.http_headers().clone();
headers.remove(HeaderName::from_static("date"));
headers
}
pub fn remote_address(&self) -> Option<SocketAddr> {
self.remote_address
}
pub fn errors(&self) -> Vec<ServerError> {
self.full_response.errors.clone()
}
pub fn usage(&self) -> Result<Option<BTreeMap<String, u64>>, ClientError> {
Ok(match self.full_response.extensions.get("usage").cloned() {
Some(Value::Object(obj)) => Some(
obj.into_iter()
.map(|(k, v)| match v {
Value::Number(n) => {
n.as_u64().ok_or(ClientError::InvalidUsageNumber {
usage_name: k.to_string(),
usage_number: n,
})
}
.map(|q| (k.to_string(), q)),
_ => Err(ClientError::InvalidUsageValue {
usage_name: k.to_string(),
usage_value: v,
}),
})
.collect::<Result<BTreeMap<String, u64>, ClientError>>()?,
),
_ => None,
})
}
}