Skip to content

Commit 27f92d1

Browse files
committed
Improvements and corrections
1 parent 4493028 commit 27f92d1

File tree

3 files changed

+76
-57
lines changed

3 files changed

+76
-57
lines changed

juniper_hyper/CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ All user visible changes to `juniper_hyper` crate will be documented in this fil
1010

1111
### BC Breaks
1212

13-
- Bumped up [MSRV] to 1.75. ([#1272])
13+
- Bumped up [MSRV] to 1.79. ([#1263])
14+
- Made `hyper::Request` in `graphql()` and `graphql_sync()` functions generic over `T: hyper::body::Body`. ([#1263], [#1102])
1415

15-
[#1272]: /../../pull/1272
16+
[#1102]: /../../issues/1102
17+
[#1263]: /../../pull/1263
1618

1719

1820

@@ -25,12 +27,10 @@ All user visible changes to `juniper_hyper` crate will be documented in this fil
2527
- Switched to 0.16 version of [`juniper` crate].
2628
- Switched to 1 version of [`hyper` crate]. ([#1217])
2729
- Changed return type of all functions from `Response<Body>` to `Response<String>`. ([#1101], [#1096])
28-
- Add support for `Request<T>` where `T` is a type that implements `hyper::body::Body` trait. ([#1263])
2930

3031
[#1096]: /../../issues/1096
3132
[#1101]: /../../pull/1101
3233
[#1217]: /../../pull/1217
33-
[#1263]: /../../pull/1263
3434

3535

3636

juniper_hyper/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "juniper_hyper"
33
version = "0.9.0"
44
edition = "2021"
5-
rust-version = "1.75"
5+
rust-version = "1.79"
66
description = "`juniper` GraphQL integration with `hyper`."
77
license = "BSD-2-Clause"
88
authors = [

juniper_hyper/src/lib.rs

Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{error::Error, fmt, string::FromUtf8Error, sync::Arc};
44

55
use http_body_util::BodyExt as _;
66
use hyper::{
7-
body,
7+
body::Body,
88
header::{self, HeaderValue},
99
Method, Request, Response, StatusCode,
1010
};
@@ -15,14 +15,7 @@ use juniper::{
1515
use serde_json::error::Error as SerdeError;
1616
use url::form_urlencoded;
1717

18-
pub async fn graphql_sync<
19-
CtxT,
20-
QueryT,
21-
MutationT,
22-
SubscriptionT,
23-
S,
24-
T: body::Body<Error = impl Error + 'static>,
25-
>(
18+
pub async fn graphql_sync<CtxT, QueryT, MutationT, SubscriptionT, S, T>(
2619
root_node: Arc<RootNode<'static, QueryT, MutationT, SubscriptionT, S>>,
2720
context: Arc<CtxT>,
2821
req: Request<T>,
@@ -36,21 +29,15 @@ where
3629
SubscriptionT::TypeInfo: Sync,
3730
CtxT: Sync,
3831
S: ScalarValue + Send + Sync,
32+
T: Body<Error: fmt::Display>,
3933
{
4034
match parse_req(req).await {
4135
Ok(req) => execute_request_sync(root_node, context, req).await,
4236
Err(resp) => resp,
4337
}
4438
}
4539

46-
pub async fn graphql<
47-
CtxT,
48-
QueryT,
49-
MutationT,
50-
SubscriptionT,
51-
S,
52-
T: body::Body<Error = impl Error + 'static>,
53-
>(
40+
pub async fn graphql<CtxT, QueryT, MutationT, SubscriptionT, S, T>(
5441
root_node: Arc<RootNode<'static, QueryT, MutationT, SubscriptionT, S>>,
5542
context: Arc<CtxT>,
5643
req: Request<T>,
@@ -64,16 +51,19 @@ where
6451
SubscriptionT::TypeInfo: Sync,
6552
CtxT: Sync,
6653
S: ScalarValue + Send + Sync,
54+
T: Body<Error: fmt::Display>,
6755
{
6856
match parse_req(req).await {
6957
Ok(req) => execute_request(root_node, context, req).await,
7058
Err(resp) => resp,
7159
}
7260
}
7361

74-
async fn parse_req<S: ScalarValue, T: body::Body<Error = impl Error + 'static>>(
75-
req: Request<T>,
76-
) -> Result<GraphQLBatchRequest<S>, Response<String>> {
62+
async fn parse_req<S, T>(req: Request<T>) -> Result<GraphQLBatchRequest<S>, Response<String>>
63+
where
64+
S: ScalarValue,
65+
T: Body<Error: fmt::Display>,
66+
{
7767
match *req.method() {
7868
Method::GET => parse_get_req(req),
7969
Method::POST => {
@@ -92,9 +82,11 @@ async fn parse_req<S: ScalarValue, T: body::Body<Error = impl Error + 'static>>(
9282
.map_err(render_error)
9383
}
9484

95-
fn parse_get_req<S: ScalarValue, T: body::Body<Error = impl Error + 'static>>(
96-
req: Request<T>,
97-
) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>> {
85+
fn parse_get_req<S, T>(req: Request<T>) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>>
86+
where
87+
S: ScalarValue,
88+
T: Body,
89+
{
9890
req.uri()
9991
.query()
10092
.map(|q| gql_request_from_get(q).map(GraphQLBatchRequest::Single))
@@ -105,9 +97,13 @@ fn parse_get_req<S: ScalarValue, T: body::Body<Error = impl Error + 'static>>(
10597
})
10698
}
10799

108-
async fn parse_post_json_req<S: ScalarValue, T: body::Body<Error = impl Error + 'static>>(
100+
async fn parse_post_json_req<S, T>(
109101
body: T,
110-
) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>> {
102+
) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>>
103+
where
104+
S: ScalarValue,
105+
T: Body,
106+
{
111107
let chunk = body
112108
.collect()
113109
.await
@@ -120,9 +116,13 @@ async fn parse_post_json_req<S: ScalarValue, T: body::Body<Error = impl Error +
120116
.map_err(GraphQLRequestError::BodyJSONError)
121117
}
122118

123-
async fn parse_post_graphql_req<S: ScalarValue, T: body::Body>(
119+
async fn parse_post_graphql_req<S, T>(
124120
body: T,
125-
) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>> {
121+
) -> Result<GraphQLBatchRequest<S>, GraphQLRequestError<T>>
122+
where
123+
S: ScalarValue,
124+
T: Body,
125+
{
126126
let chunk = body
127127
.collect()
128128
.await
@@ -157,9 +157,10 @@ pub async fn playground(
157157
resp
158158
}
159159

160-
fn render_error<T: body::Body<Error = impl Error + 'static>>(
161-
err: GraphQLRequestError<T>,
162-
) -> Response<String> {
160+
fn render_error<T>(err: GraphQLRequestError<T>) -> Response<String>
161+
where
162+
T: Body<Error: fmt::Display>,
163+
{
163164
let mut resp = new_response(StatusCode::BAD_REQUEST);
164165
*resp.body_mut() = err.to_string();
165166
resp
@@ -227,11 +228,12 @@ where
227228
resp
228229
}
229230

230-
fn gql_request_from_get<S, T: body::Body>(
231+
fn gql_request_from_get<S, T>(
231232
input: &str,
232233
) -> Result<JuniperGraphQLRequest<S>, GraphQLRequestError<T>>
233234
where
234235
S: ScalarValue,
236+
T: Body,
235237
{
236238
let mut query = None;
237239
let mut operation_name = None;
@@ -272,7 +274,7 @@ where
272274
}
273275
}
274276

275-
fn invalid_err<T: body::Body>(parameter_name: &str) -> GraphQLRequestError<T> {
277+
fn invalid_err<T: Body>(parameter_name: &str) -> GraphQLRequestError<T> {
276278
GraphQLRequestError::Invalid(format!(
277279
"`{parameter_name}` parameter is specified multiple times",
278280
))
@@ -293,38 +295,57 @@ fn new_html_response(code: StatusCode) -> Response<String> {
293295
resp
294296
}
295297

296-
#[derive(Debug)]
297-
enum GraphQLRequestError<T: body::Body> {
298+
enum GraphQLRequestError<T: Body> {
298299
BodyHyper(T::Error),
299300
BodyUtf8(FromUtf8Error),
300301
BodyJSONError(SerdeError),
301302
Variables(SerdeError),
302303
Invalid(String),
303304
}
304305

305-
impl<T: body::Body<Error = impl Error + 'static>> fmt::Display for GraphQLRequestError<T> {
306+
// NOTE: Manual implementation instead of `#[derive(Debug)]` is used to omit imposing unnecessary
307+
// `T: Debug` bound on the implementation.
308+
impl<T> fmt::Debug for GraphQLRequestError<T>
309+
where
310+
T: Body<Error: fmt::Debug>,
311+
{
312+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
313+
match self {
314+
Self::BodyHyper(e) => fmt::Debug::fmt(e, f),
315+
Self::BodyUtf8(e) => fmt::Debug::fmt(e, f),
316+
Self::BodyJSONError(e) => fmt::Debug::fmt(e, f),
317+
Self::Variables(e) => fmt::Debug::fmt(e, f),
318+
Self::Invalid(e) => fmt::Debug::fmt(e, f),
319+
}
320+
}
321+
}
322+
323+
impl<T> fmt::Display for GraphQLRequestError<T>
324+
where
325+
T: Body<Error: fmt::Display>,
326+
{
306327
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
307328
match self {
308-
GraphQLRequestError::BodyHyper(err) => fmt::Display::fmt(err, f),
309-
GraphQLRequestError::BodyUtf8(err) => fmt::Display::fmt(err, f),
310-
GraphQLRequestError::BodyJSONError(err) => fmt::Display::fmt(err, f),
311-
GraphQLRequestError::Variables(err) => fmt::Display::fmt(err, f),
312-
GraphQLRequestError::Invalid(err) => fmt::Display::fmt(err, f),
329+
Self::BodyHyper(e) => fmt::Display::fmt(e, f),
330+
Self::BodyUtf8(e) => fmt::Display::fmt(e, f),
331+
Self::BodyJSONError(e) => fmt::Display::fmt(e, f),
332+
Self::Variables(e) => fmt::Display::fmt(e, f),
333+
Self::Invalid(e) => fmt::Display::fmt(e, f),
313334
}
314335
}
315336
}
316337

317-
impl<T: body::Body<Error = impl Error + 'static> + std::fmt::Debug> Error for GraphQLRequestError<T>
338+
impl<T> Error for GraphQLRequestError<T>
318339
where
319-
<T as body::Body>::Error: std::fmt::Debug,
340+
T: Body<Error: Error + 'static>,
320341
{
321342
fn source(&self) -> Option<&(dyn Error + 'static)> {
322343
match self {
323-
GraphQLRequestError::BodyHyper(err) => Some(err),
324-
GraphQLRequestError::BodyUtf8(err) => Some(err),
325-
GraphQLRequestError::BodyJSONError(err) => Some(err),
326-
GraphQLRequestError::Variables(err) => Some(err),
327-
GraphQLRequestError::Invalid(_) => None,
344+
Self::BodyHyper(e) => Some(e),
345+
Self::BodyUtf8(e) => Some(e),
346+
Self::BodyJSONError(e) => Some(e),
347+
Self::Variables(e) => Some(e),
348+
Self::Invalid(_) => None,
328349
}
329350
}
330351
}
@@ -335,7 +356,7 @@ mod tests {
335356
convert::Infallible, error::Error, net::SocketAddr, panic, sync::Arc, time::Duration,
336357
};
337358

338-
use http_body_util::BodyExt;
359+
use http_body_util::BodyExt as _;
339360
use hyper::{
340361
body::Incoming, server::conn::http1, service::service_fn, Method, Request, Response,
341362
StatusCode,
@@ -513,14 +534,12 @@ mod tests {
513534
}
514535

515536
#[tokio::test]
516-
/// run test for a custom request type - `Request<Vec<u8>>`
517-
async fn test_custom_hyper_integration() {
537+
async fn test_custom_request_hyper_integration() {
518538
run_hyper_integration(3002, false, false).await
519539
}
520540

521541
#[tokio::test]
522-
/// run test for a custom request type - `Request<Vec<u8>>` in sync mode
523-
async fn test_custom_sync_hyper_integration() {
542+
async fn test_custom_request_sync_hyper_integration() {
524543
run_hyper_integration(3003, true, true).await
525544
}
526545
}

0 commit comments

Comments
 (0)