Skip to content

Commit 904a45e

Browse files
committed
tide::Server implements http_client::HttpClient
1 parent 146dc66 commit 904a45e

File tree

10 files changed

+194
-143
lines changed

10 files changed

+194
-143
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ async-std = { version = "1.6.0", features = ["unstable"] }
4141
async-trait = "0.1.36"
4242
femme = { version = "2.0.1", optional = true }
4343
futures-util = "0.3.5"
44-
log = { version = "0.4.8", features = ["std"] }
44+
http-client = { version = "6.0.0", default-features = false }
4545
http-types = "2.2.1"
4646
kv-log-macro = "1.0.4"
47+
log = { version = "0.4.8", features = ["std"] }
4748
pin-project-lite = "0.1.7"
4849
route-recognizer = "0.2.0"
4950
serde = "1.0.102"
@@ -57,7 +58,7 @@ lazy_static = "1.4.0"
5758
logtest = "2.0.0"
5859
portpicker = "0.1.0"
5960
serde = { version = "1.0.102", features = ["derive"] }
60-
surf = { version = "2.0.0-alpha.3", default-features = false, features = ["h1-client"] }
61+
surf = { version = "2.0.0-alpha.7", default-features = false, features = ["h1-client"] }
6162
tempfile = "3.1.0"
6263

6364
[[test]]

src/server.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::log;
99
use crate::middleware::{Middleware, Next};
1010
use crate::router::{Router, Selection};
1111
use crate::{Endpoint, Request, Route};
12+
1213
/// An HTTP server.
1314
///
1415
/// Servers are built up as a combination of *state*, *endpoints* and *middleware*:
@@ -24,7 +25,6 @@ use crate::{Endpoint, Request, Route};
2425
/// - Middleware extends the base Tide framework with additional request or
2526
/// response processing, such as compression, default headers, or logging. To
2627
/// add middleware to an app, use the [`Server::middleware`] method.
27-
#[allow(missing_debug_implementations)]
2828
pub struct Server<State> {
2929
router: Arc<Router<State>>,
3030
state: State,
@@ -253,6 +253,12 @@ impl<State: Clone + Send + Sync + 'static> Server<State> {
253253
}
254254
}
255255

256+
impl<State: Send + Sync + 'static> std::fmt::Debug for Server<State> {
257+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258+
f.debug_struct("Server").finish()
259+
}
260+
}
261+
256262
impl<State: Clone> Clone for Server<State> {
257263
fn clone(&self) -> Self {
258264
Self {
@@ -292,6 +298,13 @@ impl<State: Clone + Sync + Send + 'static, InnerState: Clone + Sync + Send + 'st
292298
}
293299
}
294300

301+
#[crate::utils::async_trait]
302+
impl<State: Clone + Send + Sync + Unpin + 'static> http_client::HttpClient for Server<State> {
303+
async fn send(&self, req: crate::http::Request) -> crate::http::Result<crate::http::Response> {
304+
self.respond(req).await
305+
}
306+
}
307+
295308
#[cfg(test)]
296309
mod test {
297310
use crate as tide;

tests/log.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ mod test_utils;
55
use test_utils::ServerTestingExt;
66

77
#[async_std::test]
8-
async fn log_tests() {
8+
async fn log_tests() -> tide::Result<()> {
99
let mut logger = logtest::start();
1010
test_server_listen(&mut logger).await;
11-
test_only_log_once(&mut logger).await;
11+
test_only_log_once(&mut logger).await?;
12+
Ok(())
1213
}
1314

1415
async fn test_server_listen(logger: &mut logtest::Logger) {
@@ -29,14 +30,14 @@ async fn test_server_listen(logger: &mut logtest::Logger) {
2930
);
3031
}
3132

32-
async fn test_only_log_once(logger: &mut logtest::Logger) {
33+
async fn test_only_log_once(logger: &mut logtest::Logger) -> tide::Result<()> {
3334
let mut app = tide::new();
3435
app.at("/").nest({
3536
let mut app = tide::new();
3637
app.at("/").get(|_| async { Ok("nested") });
3738
app
3839
});
39-
app.get("/").await;
40+
assert!(app.get("/").await?.status().is_success());
4041

4142
let entries: Vec<_> = logger.collect();
4243

@@ -55,4 +56,5 @@ async fn test_only_log_once(logger: &mut logtest::Logger) {
5556
.filter(|entry| entry.args() == "--> Response sent")
5657
.count()
5758
);
59+
Ok(())
5860
}

tests/nested.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod test_utils;
22
use test_utils::ServerTestingExt;
33

44
#[async_std::test]
5-
async fn nested() {
5+
async fn nested() -> tide::Result<()> {
66
let mut inner = tide::new();
77
inner.at("/foo").get(|_| async { Ok("foo") });
88
inner.at("/bar").get(|_| async { Ok("bar") });
@@ -11,12 +11,13 @@ async fn nested() {
1111
// Nest the inner app on /foo
1212
outer.at("/foo").nest(inner);
1313

14-
assert_eq!(outer.get_body("/foo/foo").await, "foo");
15-
assert_eq!(outer.get_body("/foo/bar").await, "bar");
14+
assert_eq!(outer.get("/foo/foo").recv_string().await?, "foo");
15+
assert_eq!(outer.get("/foo/bar").recv_string().await?, "bar");
16+
Ok(())
1617
}
1718

1819
#[async_std::test]
19-
async fn nested_middleware() {
20+
async fn nested_middleware() -> tide::Result<()> {
2021
let echo_path = |req: tide::Request<()>| async move { Ok(req.url().path().to_string()) };
2122
let mut app = tide::new();
2223
let mut inner_app = tide::new();
@@ -29,24 +30,25 @@ async fn nested_middleware() {
2930
app.at("/foo").nest(inner_app);
3031
app.at("/bar").get(echo_path);
3132

32-
let mut res = app.get("/foo/echo").await;
33+
let mut res = app.get("/foo/echo").await?;
3334
assert_eq!(res["X-Tide-Test"], "1");
3435
assert_eq!(res.status(), 200);
35-
assert_eq!(res.body_string().await.unwrap(), "/echo");
36+
assert_eq!(res.body_string().await?, "/echo");
3637

37-
let mut res = app.get("/foo/x/bar").await;
38+
let mut res = app.get("/foo/x/bar").await?;
3839
assert_eq!(res["X-Tide-Test"], "1");
3940
assert_eq!(res.status(), 200);
40-
assert_eq!(res.body_string().await.unwrap(), "/");
41+
assert_eq!(res.body_string().await?, "/");
4142

42-
let mut res = app.get("/bar").await;
43+
let mut res = app.get("/bar").await?;
4344
assert!(res.header("X-Tide-Test").is_none());
4445
assert_eq!(res.status(), 200);
45-
assert_eq!(res.body_string().await.unwrap(), "/bar");
46+
assert_eq!(res.body_string().await?, "/bar");
47+
Ok(())
4648
}
4749

4850
#[async_std::test]
49-
async fn nested_with_different_state() {
51+
async fn nested_with_different_state() -> tide::Result<()> {
5052
let mut outer = tide::new();
5153
let mut inner = tide::with_state(42);
5254
inner.at("/").get(|req: tide::Request<i32>| async move {
@@ -56,6 +58,7 @@ async fn nested_with_different_state() {
5658
outer.at("/").get(|_| async { Ok("Hello, world!") });
5759
outer.at("/foo").nest(inner);
5860

59-
assert_eq!(outer.get_body("/foo").await, "the number is 42");
60-
assert_eq!(outer.get_body("/").await, "Hello, world!");
61+
assert_eq!(outer.get("/foo").recv_string().await?, "the number is 42");
62+
assert_eq!(outer.get("/").recv_string().await?, "Hello, world!");
63+
Ok(())
6164
}

tests/response.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ async fn string_content_type() {
3636
}
3737

3838
#[async_std::test]
39-
async fn json_content_type() {
39+
async fn json_content_type() -> tide::Result<()> {
4040
use std::collections::BTreeMap;
4141
use tide::Body;
4242

@@ -51,7 +51,7 @@ async fn json_content_type() {
5151
Ok(resp)
5252
});
5353

54-
let mut resp = app.get("/json_content_type").await;
54+
let mut resp = app.get("/json_content_type").await?;
5555
assert_eq!(resp.status(), StatusCode::InternalServerError);
5656
assert_eq!(resp.body_string().await.unwrap(), "");
5757

@@ -68,6 +68,8 @@ async fn json_content_type() {
6868
assert_eq!(resp.status(), StatusCode::Ok);
6969
let body = resp.take_body().into_bytes().await.unwrap();
7070
assert_eq!(body, br##"{"a":2,"b":4,"c":6}"##);
71+
72+
Ok(())
7173
}
7274

7375
#[test]

tests/route_middleware.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async fn echo_path<State>(req: tide::Request<State>) -> tide::Result<String> {
3131
}
3232

3333
#[async_std::test]
34-
async fn route_middleware() {
34+
async fn route_middleware() -> tide::Result<()> {
3535
let mut app = tide::new();
3636
let mut foo_route = app.at("/foo");
3737
foo_route // /foo
@@ -46,17 +46,18 @@ async fn route_middleware() {
4646
.reset_middleware()
4747
.put(echo_path);
4848

49-
assert_eq!(app.get("/foo").await["X-Foo"], "foo");
50-
assert_eq!(app.post("/foo").await["X-Foo"], "foo");
51-
assert!(app.put("/foo").await.header("X-Foo").is_none());
49+
assert_eq!(app.get("/foo").await?["X-Foo"], "foo");
50+
assert_eq!(app.post("/foo").await?["X-Foo"], "foo");
51+
assert!(app.put("/foo").await?.header("X-Foo").is_none());
5252

53-
let res = app.get("/foo/bar").await;
53+
let res = app.get("/foo/bar").await?;
5454
assert_eq!(res["X-Foo"], "foo");
5555
assert_eq!(res["x-bar"], "bar");
56+
Ok(())
5657
}
5758

5859
#[async_std::test]
59-
async fn app_and_route_middleware() {
60+
async fn app_and_route_middleware() -> tide::Result<()> {
6061
let mut app = tide::new();
6162
app.with(TestMiddleware::with_header_name("X-Root", "root"));
6263
app.at("/foo")
@@ -66,19 +67,20 @@ async fn app_and_route_middleware() {
6667
.with(TestMiddleware::with_header_name("X-Bar", "bar"))
6768
.get(echo_path);
6869

69-
let res = app.get("/foo").await;
70+
let res = app.get("/foo").await?;
7071
assert_eq!(res["X-Root"], "root");
7172
assert_eq!(res["x-foo"], "foo");
7273
assert!(res.header("x-bar").is_none());
7374

74-
let res = app.get("/bar").await;
75+
let res = app.get("/bar").await?;
7576
assert_eq!(res["X-Root"], "root");
7677
assert!(res.header("x-foo").is_none());
7778
assert_eq!(res["X-Bar"], "bar");
79+
Ok(())
7880
}
7981

8082
#[async_std::test]
81-
async fn nested_app_with_route_middleware() {
83+
async fn nested_app_with_route_middleware() -> tide::Result<()> {
8284
let mut inner = tide::new();
8385
inner.with(TestMiddleware::with_header_name("X-Inner", "inner"));
8486
inner
@@ -95,23 +97,24 @@ async fn nested_app_with_route_middleware() {
9597
.with(TestMiddleware::with_header_name("X-Bar", "bar"))
9698
.nest(inner);
9799

98-
let res = app.get("/foo").await;
100+
let res = app.get("/foo").await?;
99101
assert_eq!(res["X-Root"], "root");
100102
assert!(res.header("X-Inner").is_none());
101103
assert_eq!(res["X-Foo"], "foo");
102104
assert!(res.header("X-Bar").is_none());
103105
assert!(res.header("X-Baz").is_none());
104106

105-
let res = app.get("/bar/baz").await;
107+
let res = app.get("/bar/baz").await?;
106108
assert_eq!(res["X-Root"], "root");
107109
assert_eq!(res["X-Inner"], "inner");
108110
assert!(res.header("X-Foo").is_none());
109111
assert_eq!(res["X-Bar"], "bar");
110112
assert_eq!(res["X-Baz"], "baz");
113+
Ok(())
111114
}
112115

113116
#[async_std::test]
114-
async fn subroute_not_nested() {
117+
async fn subroute_not_nested() -> tide::Result<()> {
115118
let mut app = tide::new();
116119
app.at("/parent") // /parent
117120
.with(TestMiddleware::with_header_name("X-Parent", "Parent"))
@@ -120,7 +123,8 @@ async fn subroute_not_nested() {
120123
.with(TestMiddleware::with_header_name("X-Child", "child"))
121124
.get(echo_path);
122125

123-
let res = app.get("/parent/child").await;
126+
let res = app.get("/parent/child").await?;
124127
assert!(res.header("X-Parent").is_none());
125128
assert_eq!(res["x-child"], "child");
129+
Ok(())
126130
}

tests/server.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
77
use tide::{Body, Request};
88

99
#[test]
10-
fn hello_world() -> Result<(), http_types::Error> {
10+
fn hello_world() -> tide::Result<()> {
1111
task::block_on(async {
1212
let port = test_utils::find_port().await;
1313
let server = task::spawn(async move {
@@ -25,7 +25,7 @@ fn hello_world() -> Result<(), http_types::Error> {
2525
let client = task::spawn(async move {
2626
task::sleep(Duration::from_millis(100)).await;
2727
let string = surf::get(format!("http://localhost:{}", port))
28-
.body("nori".to_string())
28+
.body(Body::from_string("nori".to_string()))
2929
.recv_string()
3030
.await
3131
.unwrap();
@@ -38,7 +38,7 @@ fn hello_world() -> Result<(), http_types::Error> {
3838
}
3939

4040
#[test]
41-
fn echo_server() -> Result<(), http_types::Error> {
41+
fn echo_server() -> tide::Result<()> {
4242
task::block_on(async {
4343
let port = test_utils::find_port().await;
4444
let server = task::spawn(async move {
@@ -52,7 +52,7 @@ fn echo_server() -> Result<(), http_types::Error> {
5252
let client = task::spawn(async move {
5353
task::sleep(Duration::from_millis(100)).await;
5454
let string = surf::get(format!("http://localhost:{}", port))
55-
.body("chashu".to_string())
55+
.body(Body::from_string("chashu".to_string()))
5656
.recv_string()
5757
.await
5858
.unwrap();
@@ -65,7 +65,7 @@ fn echo_server() -> Result<(), http_types::Error> {
6565
}
6666

6767
#[test]
68-
fn json() -> Result<(), http_types::Error> {
68+
fn json() -> tide::Result<()> {
6969
#[derive(Deserialize, Serialize)]
7070
struct Counter {
7171
count: usize,

0 commit comments

Comments
 (0)