1
1
use rand:: Rng ;
2
2
use serde:: Serialize ;
3
3
use std:: collections:: HashMap ;
4
- use warp:: { Filter , Rejection } ;
4
+ use warp:: { http :: StatusCode , reject :: Reject , Filter , Rejection , Reply } ;
5
5
6
6
#[ derive( Debug , Serialize ) ]
7
7
struct Randnum {
8
8
num : i32 ,
9
9
}
10
10
11
+ #[ derive( Debug ) ]
12
+ enum Error {
13
+ ParseError ( std:: num:: ParseIntError ) ,
14
+ BadRange ,
15
+ }
16
+
17
+ impl Reject for Error { }
18
+
19
+ impl std:: fmt:: Display for Error {
20
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
21
+ match * self {
22
+ Error :: ParseError ( ref err) => write ! ( f, "Cannot parse parameter: {}" , err) ,
23
+ Error :: BadRange => write ! ( f, "BadRange" ) ,
24
+ }
25
+ }
26
+ }
27
+
11
28
impl Randnum {
12
- fn new ( start : Option < i32 > , end : Option < i32 > ) -> Self {
29
+ fn new ( start : Option < i32 > , end : Option < i32 > ) -> Result < Self , Rejection > {
13
30
let start = match start {
14
31
Some ( n) => n,
15
32
_ => 1 ,
@@ -20,29 +37,45 @@ impl Randnum {
20
37
_ => 1000 ,
21
38
} ;
22
39
40
+ if start <= 0 || end <= 0 || end < start {
41
+ return Err ( warp:: reject:: custom ( Error :: BadRange ) ) ;
42
+ }
43
+
23
44
let random = {
24
45
let mut rng = rand:: thread_rng ( ) ;
25
46
rng. gen_range ( start..=end)
26
47
} ;
27
48
28
- Self { num : random }
49
+ Ok ( Self { num : random } )
50
+ }
51
+ }
52
+
53
+ async fn return_error ( r : Rejection ) -> Result < impl Reply , Rejection > {
54
+ if let Some ( error) = r. find :: < Error > ( ) {
55
+ Ok ( warp:: reply:: with_status (
56
+ error. to_string ( ) ,
57
+ StatusCode :: RANGE_NOT_SATISFIABLE ,
58
+ ) )
59
+ } else {
60
+ Ok ( warp:: reply:: with_status (
61
+ "Route not found" . to_string ( ) ,
62
+ StatusCode :: NOT_FOUND ,
63
+ ) )
29
64
}
30
65
}
31
66
32
- async fn get_random ( params : HashMap < String , String > ) -> Result < impl warp :: Reply , Rejection > {
67
+ async fn get_random ( params : HashMap < String , String > ) -> Result < impl Reply , Rejection > {
33
68
let start = match params. get ( "start" ) {
34
- Some ( n) => Some ( n. parse :: < i32 > ( ) . expect ( "Could not parse start" ) ) ,
69
+ Some ( n) => Some ( n. parse :: < i32 > ( ) . map_err ( Error :: ParseError ) ? ) ,
35
70
None => None ,
36
71
} ;
37
72
38
73
let end = match params. get ( "end" ) {
39
- Some ( n) => Some ( n. parse :: < i32 > ( ) . expect ( "Could not parse end" ) ) ,
74
+ Some ( n) => Some ( n. parse :: < i32 > ( ) . map_err ( Error :: ParseError ) ? ) ,
40
75
None => None ,
41
76
} ;
42
77
43
- println ! ( "start:{:?}, end:{:?}" , start, end) ;
44
-
45
- let random_number = Randnum :: new ( start, end) ;
78
+ let random_number = Randnum :: new ( start, end) ?;
46
79
47
80
Ok ( warp:: reply:: json ( & random_number) )
48
81
}
@@ -55,6 +88,7 @@ async fn main() {
55
88
. and ( warp:: query ( ) )
56
89
. and_then ( get_random) ;
57
90
58
- let route = get_random;
59
- warp:: serve ( route) . run ( ( [ 127 , 0 , 0 , 1 ] , 1337 ) ) . await ;
91
+ let routes = get_random. recover ( return_error) ;
92
+
93
+ warp:: serve ( routes) . run ( ( [ 127 , 0 , 0 , 1 ] , 1337 ) ) . await ;
60
94
}
0 commit comments