-
-
Notifications
You must be signed in to change notification settings - Fork 709
/
anyhow.rs
61 lines (46 loc) · 1.46 KB
/
anyhow.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#![deny(warnings)]
use serde::export::Formatter;
use warp::http::StatusCode;
use warp::{Filter, Rejection, Reply};
#[tokio::main]
async fn main() {
let is_even = warp::path!("is_even" / u64).and_then(handler);
let routes = warp::get().and(is_even).recover(handle_rejection);
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
}
async fn handler(number: u64) -> anyhow::Result<impl Reply> {
if number > 100 {
anyhow::bail!(TooBig)
}
if number % 2 == 1 {
anyhow::bail!(NotEven)
}
return Ok(StatusCode::OK);
}
#[derive(Debug)]
struct TooBig;
impl std::fmt::Display for TooBig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "sorry, we can't handle big numbers like this")
}
}
#[derive(Debug)]
struct NotEven;
impl std::fmt::Display for NotEven {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "the given number is not even")
}
}
async fn handle_rejection(err: Rejection) -> Result<impl Reply, Rejection> {
if let Some(anyhow) = err.find::<anyhow::Error>() {
// here we can downcast the anyhow error to whatever we want
if let Some(_) = anyhow.downcast_ref::<TooBig>() {
return Ok(StatusCode::INTERNAL_SERVER_ERROR);
}
if let Some(_) = anyhow.downcast_ref::<NotEven>() {
return Ok(StatusCode::BAD_REQUEST);
}
return Ok(StatusCode::INTERNAL_SERVER_ERROR);
}
Err(err)
}