Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit c50b035

Browse files
committed
DRY in Hrana over HTTP
1 parent e2bd4d2 commit c50b035

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

sqld/src/http/hrana_over_http.rs

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use anyhow::{anyhow, Context, Result};
22
use serde::{de::DeserializeOwned, Deserialize, Serialize};
3+
use std::future::Future;
34
use std::sync::Arc;
45

56
use crate::database::service::DbFactory;
7+
use crate::database::Database;
68
use crate::{batch, hrana};
79

810
#[derive(thiserror::Error, Debug)]
@@ -41,27 +43,17 @@ pub async fn handle_execute(
4143
result: batch::proto::StmtResult,
4244
}
4345

44-
let res: Result<_> = async move {
45-
let req_body = json_request_body::<ReqBody>(req.into_body()).await?;
46-
let db = db_factory
47-
.create()
48-
.await
49-
.context("Could not create a database connection")?;
50-
let result = batch::execute_stmt(&*db, &req_body.stmt)
46+
handle_request(db_factory, req, |db, req_body: ReqBody| async move {
47+
batch::execute_stmt(&*db, &req_body.stmt)
5148
.await
49+
.map(|result| RespBody { result })
5250
.map_err(|err| match err.downcast::<batch::StmtError>() {
5351
Ok(stmt_err) => anyhow!(ResponseError::Stmt(stmt_err)),
5452
Err(err) => err,
5553
})
56-
.context("Could not execute statement")?;
57-
Ok(json_response(hyper::StatusCode::OK, &RespBody { result }))
58-
}
59-
.await;
60-
61-
Ok(match res {
62-
Ok(resp) => resp,
63-
Err(err) => error_response(err.downcast::<ResponseError>()?),
54+
.context("Could not execute statement")
6455
})
56+
.await
6557
}
6658

6759
pub async fn handle_batch(
@@ -78,20 +70,42 @@ pub async fn handle_batch(
7870
result: batch::proto::BatchResult,
7971
}
8072

81-
let res: Result<_> = async move {
82-
let req_body = json_request_body::<ReqBody>(req.into_body()).await?;
83-
let db = db_factory
84-
.create()
85-
.await
86-
.context("Could not create a database connection")?;
87-
let result = batch::execute_batch(&*db, &req_body.batch)
73+
handle_request(db_factory, req, |db, req_body: ReqBody| async move {
74+
batch::execute_batch(&*db, &req_body.batch)
8875
.await
76+
.map(|result| RespBody { result })
8977
.map_err(|err| match err.downcast::<batch::BatchError>() {
9078
Ok(batch_err) => anyhow!(ResponseError::Batch(batch_err)),
9179
Err(err) => err,
9280
})
93-
.context("Could not execute batch")?;
94-
Ok(json_response(hyper::StatusCode::OK, &RespBody { result }))
81+
.context("Could not execute batch")
82+
})
83+
.await
84+
}
85+
86+
async fn handle_request<ReqBody, RespBody, F, Fut>(
87+
db_factory: Arc<dyn DbFactory>,
88+
req: hyper::Request<hyper::Body>,
89+
f: F,
90+
) -> Result<hyper::Response<hyper::Body>>
91+
where
92+
ReqBody: DeserializeOwned,
93+
RespBody: Serialize,
94+
F: FnOnce(Arc<dyn Database>, ReqBody) -> Fut,
95+
Fut: Future<Output = Result<RespBody>>,
96+
{
97+
let res: Result<_> = async move {
98+
let req_body = hyper::body::to_bytes(req.into_body()).await?;
99+
let req_body = serde_json::from_slice(&req_body)
100+
.map_err(|e| ResponseError::BadRequestBody { source: e })?;
101+
102+
let db = db_factory
103+
.create()
104+
.await
105+
.context("Could not create a database connection")?;
106+
let resp_body = f(db, req_body).await?;
107+
108+
Ok(json_response(hyper::StatusCode::OK, &resp_body))
95109
}
96110
.await;
97111

@@ -101,13 +115,6 @@ pub async fn handle_batch(
101115
})
102116
}
103117

104-
async fn json_request_body<T: DeserializeOwned>(body: hyper::Body) -> Result<T> {
105-
let body = hyper::body::to_bytes(body).await?;
106-
let body =
107-
serde_json::from_slice(&body).map_err(|e| ResponseError::BadRequestBody { source: e })?;
108-
Ok(body)
109-
}
110-
111118
fn error_response(err: ResponseError) -> hyper::Response<hyper::Body> {
112119
use batch::{BatchError, StmtError};
113120
let status = match &err {

0 commit comments

Comments
 (0)