1
1
use anyhow:: { anyhow, Context , Result } ;
2
2
use serde:: { de:: DeserializeOwned , Deserialize , Serialize } ;
3
+ use std:: future:: Future ;
3
4
use std:: sync:: Arc ;
4
5
5
6
use crate :: database:: service:: DbFactory ;
7
+ use crate :: database:: Database ;
6
8
use crate :: { batch, hrana} ;
7
9
8
10
#[ derive( thiserror:: Error , Debug ) ]
@@ -41,27 +43,17 @@ pub async fn handle_execute(
41
43
result : batch:: proto:: StmtResult ,
42
44
}
43
45
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 )
51
48
. await
49
+ . map ( |result| RespBody { result } )
52
50
. map_err ( |err| match err. downcast :: < batch:: StmtError > ( ) {
53
51
Ok ( stmt_err) => anyhow ! ( ResponseError :: Stmt ( stmt_err) ) ,
54
52
Err ( err) => err,
55
53
} )
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" )
64
55
} )
56
+ . await
65
57
}
66
58
67
59
pub async fn handle_batch (
@@ -78,20 +70,42 @@ pub async fn handle_batch(
78
70
result : batch:: proto:: BatchResult ,
79
71
}
80
72
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 )
88
75
. await
76
+ . map ( |result| RespBody { result } )
89
77
. map_err ( |err| match err. downcast :: < batch:: BatchError > ( ) {
90
78
Ok ( batch_err) => anyhow ! ( ResponseError :: Batch ( batch_err) ) ,
91
79
Err ( err) => err,
92
80
} )
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) )
95
109
}
96
110
. await ;
97
111
@@ -101,13 +115,6 @@ pub async fn handle_batch(
101
115
} )
102
116
}
103
117
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
-
111
118
fn error_response ( err : ResponseError ) -> hyper:: Response < hyper:: Body > {
112
119
use batch:: { BatchError , StmtError } ;
113
120
let status = match & err {
0 commit comments