1- use std:: fmt:: { Debug , Formatter } ;
21use std:: sync:: Arc ;
32
43use crate :: archiver:: Archiver ;
54use serde:: Serialize ;
6- use warp:: reject:: Reject ;
5+ use warp:: http:: header:: CONTENT_TYPE ;
6+ use warp:: http:: { HeaderValue , StatusCode } ;
7+ use warp:: hyper:: Body ;
78use warp:: { Filter , Rejection , Reply } ;
89
910pub struct Api {
@@ -18,19 +19,16 @@ struct RearchiveResponse {
1819 block_end : u64 ,
1920}
2021
21- impl Debug for RearchiveResponse {
22- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
23- f. debug_struct ( "RearchiveResponse" )
24- . field ( "success" , & self . success )
25- . field ( "message" , & self . message )
26- . field ( "block_start" , & self . block_start )
27- . field ( "block_end" , & self . block_end )
28- . finish ( )
22+ impl Reply for RearchiveResponse {
23+ fn into_response ( self ) -> warp:: reply:: Response {
24+ let body = serde_json:: to_string ( & self ) . unwrap ( ) ;
25+ let mut res = warp:: reply:: Response :: new ( Body :: from ( body) ) ;
26+ res. headers_mut ( )
27+ . insert ( CONTENT_TYPE , HeaderValue :: from_static ( "application/json" ) ) ;
28+ res
2929 }
3030}
3131
32- impl Reject for RearchiveResponse { }
33-
3432impl Api {
3533 pub fn new ( archiver : Archiver ) -> Self {
3634 Self {
@@ -42,6 +40,7 @@ impl Api {
4240 let archiver = self . archiver . clone ( ) ;
4341 warp:: path!( "rearchive" )
4442 . and ( warp:: get ( ) )
43+ // todo: make validation error return json https://stackoverflow.com/questions/60554783/is-there-a-way-to-do-validation-as-part-of-a-filter-in-warp
4544 . and ( warp:: query :: < RearchiveQuery > ( ) )
4645 . and ( warp:: any ( ) . map ( move || archiver. clone ( ) ) )
4746 . and_then ( Self :: rearchive_range)
@@ -61,35 +60,53 @@ impl Api {
6160 archiver : Arc < Archiver > ,
6261 ) -> Result < impl Reply , Rejection > {
6362 if query. from . is_none ( ) || query. to . is_none ( ) {
64- return Err ( warp:: reject:: custom ( RearchiveResponse {
65- success : false ,
66- message : "Invalid query parameters" . to_string ( ) ,
67- block_start : 0 ,
68- block_end : 0 ,
69- } ) ) ;
63+ return Ok ( warp:: reply:: with_status (
64+ RearchiveResponse {
65+ success : false ,
66+ message : "Invalid query parameters" . to_string ( ) ,
67+ block_start : 0 ,
68+ block_end : 0 ,
69+ } ,
70+ StatusCode :: BAD_REQUEST ,
71+ ) ) ;
7072 }
7173
7274 if query. from > query. to {
73- return Err ( warp:: reject:: custom ( RearchiveResponse {
74- success : false ,
75- message : "Invalid query parameters" . to_string ( ) ,
76- block_start : 0 ,
77- block_end : 0 ,
78- } ) ) ;
75+ return Ok ( warp:: reply:: with_status (
76+ RearchiveResponse {
77+ success : false ,
78+ message : "Invalid query parameters" . to_string ( ) ,
79+ block_start : 0 ,
80+ block_end : 0 ,
81+ } ,
82+ StatusCode :: BAD_REQUEST ,
83+ ) ) ;
7984 }
8085
8186 let res = archiver
8287 . rearchive_range ( query. from . unwrap ( ) , query. to . unwrap ( ) )
8388 . await ;
8489 if res. error . is_some ( ) {
85- return Err ( warp:: reject:: custom ( RearchiveResponse {
86- success : false ,
87- message : res. error . unwrap ( ) ,
90+ return Ok ( warp:: reply:: with_status (
91+ RearchiveResponse {
92+ success : false ,
93+ message : res. error . unwrap ( ) ,
94+ block_start : 0 ,
95+ block_end : 0 ,
96+ } ,
97+ StatusCode :: INTERNAL_SERVER_ERROR ,
98+ ) ) ;
99+ }
100+
101+ Ok ( warp:: reply:: with_status (
102+ RearchiveResponse {
103+ success : true ,
104+ message : "Rearchive successful" . to_string ( ) ,
88105 block_start : res. from ,
89106 block_end : res. to ,
90- } ) ) ;
91- }
92- Ok ( warp :: reply :: json ( & res ) )
107+ } ,
108+ StatusCode :: OK ,
109+ ) )
93110 }
94111}
95112
@@ -102,6 +119,7 @@ struct RearchiveQuery {
102119#[ cfg( test) ]
103120mod tests {
104121 use std:: path:: PathBuf ;
122+ use std:: str:: from_utf8;
105123 use std:: sync:: Arc ;
106124 use std:: time:: Duration ;
107125
@@ -157,10 +175,7 @@ mod tests {
157175 . await ;
158176
159177 assert_eq ! ( res. status( ) , 200 ) ;
160- assert_eq ! (
161- std:: str :: from_utf8( res. body( ) ) . unwrap( ) ,
162- "{\" status\" :\" ok\" }"
163- ) ;
178+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" status\" :\" ok\" }" ) ;
164179 clean_dir ( dir) ;
165180 }
166181
@@ -172,12 +187,54 @@ mod tests {
172187 tokio:: fs:: create_dir_all ( dir) . await . unwrap ( ) ;
173188 let test_storage = Arc :: new ( Mutex :: new ( TestFSStorage :: new ( storage) . await . unwrap ( ) ) ) ;
174189 let ( archiver, _) = create_test_archiver ( test_storage. clone ( ) , rx) . await ;
175- let res = warp:: test:: request ( )
190+ let api = Api :: new ( archiver) ;
191+ let mut res = warp:: test:: request ( )
176192 . method ( "GET" )
177193 . path ( "/rearchive?from=2001&to=2000" )
178- . reply ( & Api :: new ( archiver) . routes ( ) )
194+ . reply ( & api. routes ( ) )
195+ . await ;
196+ assert_eq ! ( res. status( ) , 400 ) ;
197+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
198+
199+ res = warp:: test:: request ( )
200+ . method ( "GET" )
201+ . path ( "/rearchive?to=2000" )
202+ . reply ( & api. routes ( ) )
203+ . await ;
204+ assert_eq ! ( res. status( ) , 400 ) ;
205+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
206+
207+ res = warp:: test:: request ( )
208+ . method ( "GET" )
209+ . path ( "/rearchive?from=2000" )
210+ . reply ( & api. routes ( ) )
211+ . await ;
212+ assert_eq ! ( res. status( ) , 400 ) ;
213+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
214+
215+ res = warp:: test:: request ( )
216+ . method ( "GET" )
217+ . path ( "/rearchive?from=bbb&to=2000" )
218+ . reply ( & api. routes ( ) )
179219 . await ;
180- assert_eq ! ( res. status( ) , 500 ) ;
220+ assert_eq ! ( res. status( ) , 400 ) ;
221+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "Invalid query string" ) ;
222+
223+ res = warp:: test:: request ( )
224+ . method ( "GET" )
225+ . path ( "/rearchive?from=100&to=aaa" )
226+ . reply ( & api. routes ( ) )
227+ . await ;
228+ assert_eq ! ( res. status( ) , 400 ) ;
229+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "Invalid query string" ) ;
230+
231+ res = warp:: test:: request ( )
232+ . method ( "GET" )
233+ . path ( "/rearchive?from=11&to=15" )
234+ . reply ( & api. routes ( ) )
235+ . await ;
236+ assert_eq ! ( res. status( ) , 200 ) ;
237+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :true,\" message\" :\" Rearchive successful\" ,\" block_start\" :11,\" block_end\" :15}" ) ;
181238 clean_dir ( dir) ;
182239 }
183240
0 commit comments