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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
# Unwraps an `Result::Ok` or returns the `Conn` with a 500 status.

```
use trillium_testing::prelude::*;
use trillium::{Conn, conn_try};

let handler = |mut conn: Conn| async move {
  let request_body_string = conn_try!(conn.request_body_string().await, conn);
  let u8: u8 = conn_try!(request_body_string.parse(), conn);
  conn.ok(format!("received u8 as body: {}", u8))
};

assert_status!(
    post("/").with_request_body("not u8").on(&handler),
    500
);

assert_body!(
    post("/").with_request_body("10").on(&handler),
    "received u8 as body: 10"
);


```


*/
#[macro_export]
macro_rules! conn_try {
    ($expr:expr, $conn:expr) => {
        match $expr {
            Ok(value) => value,
            Err(error) => {
                $crate::log::error!("{}:{} conn_try error: {}", file!(), line!(), error);
                return $conn.with_status(500).halt();
            }
        }
    };
}

/**
# Unwraps an `Option::Some` or returns the `Conn`.

This is useful for gracefully exiting a `Handler` without
returning an error.

```
use trillium_testing::prelude::*;
use trillium::{Conn, conn_unwrap, State};

#[derive(Copy, Clone)]
struct MyState(&'static str);
let handler = |conn: trillium::Conn| async move {
  let important_state: MyState = *conn_unwrap!(conn.state(), conn);
  conn.ok(important_state.0)
};

assert_not_handled!(get("/").on(&handler)); // we never reached the conn.ok line.

assert_ok!(
    get("/").on(&(State::new(MyState("hi")), handler)),
    "hi"
);
```
*/
#[macro_export]
macro_rules! conn_unwrap {
    ($option:expr, $conn:expr) => {
        match $option {
            Some(value) => value,
            None => return $conn,
        }
    };
}

/**
# A convenience macro for logging the contents of error variants.

This is useful when there is no further action required to process the
error path, but you still want to record that it transpired
*/
#[macro_export]
macro_rules! log_error {
    ($expr:expr) => {
        if let Err(err) = $expr {
            $crate::log::error!("{}:{} {:?}", file!(), line!(), err);
        }
    };

    ($expr:expr, $message:expr) => {
        if let Err(err) = $expr {
            $crate::log::error!("{}:{} {} {:?}", file!(), line!(), $message, err);
        }
    };
}

/**
# Macro for implementing Handler for simple newtypes that contain another handler.

```
use trillium::{delegate_handler, State, Conn, conn_unwrap};
#[derive(Clone, Copy)]
struct MyState(usize);
struct MyHandler(State<MyState>);
delegate_handler!(MyHandler);
impl MyHandler {
    fn new(n: usize) -> Self {
        MyHandler(State::new(MyState(n)))
    }
}

# use trillium_testing::prelude::*;

let handler = (MyHandler::new(5), |conn: Conn| async move {
    let MyState(n) = *conn_unwrap!(conn.state(), conn);
    conn.ok(n.to_string())
});
assert_ok!(get("/").on(&handler), "5");
```
*/
#[macro_export]
macro_rules! delegate_handler {
    ($struct_name:ty) => {
        #[$crate::async_trait]
        impl $crate::Handler for $struct_name {
            async fn run(&self, conn: $crate::Conn) -> $crate::Conn {
                use $crate::Handler;
                self.0.run(conn).await
            }

            async fn init(&mut self, info: &mut $crate::Info) {
                use $crate::Handler;
                self.0.init(info).await;
            }

            async fn before_send(&self, conn: $crate::Conn) -> $crate::Conn {
                use $crate::Handler;
                self.0.before_send(conn).await
            }

            fn name(&self) -> std::borrow::Cow<'static, str> {
                use $crate::Handler;
                self.0.name()
            }

            fn has_upgrade(&self, upgrade: &$crate::Upgrade) -> bool {
                use $crate::Handler;
                self.0.has_upgrade(upgrade)
            }

            async fn upgrade(&self, upgrade: $crate::Upgrade) {
                use $crate::Handler;
                self.0.upgrade(upgrade).await;
            }
        }
    };
}