WIP: Switch to axum

Nathan Sobo created

Change summary

Cargo.lock                | 223 ++++++++++++++++++++++++++--------------
crates/collab/Cargo.toml  |   3 
crates/collab/src/api.rs  |  57 +++++-----
crates/collab/src/main.rs |  52 ++++----
4 files changed, 196 insertions(+), 139 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -177,7 +177,7 @@ dependencies = [
  "futures-core",
  "futures-io",
  "memchr",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
 ]
 
 [[package]]
@@ -340,7 +340,7 @@ dependencies = [
  "memchr",
  "num_cpus",
  "once_cell",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "pin-utils",
  "slab",
  "wasm-bindgen-futures",
@@ -385,7 +385,7 @@ dependencies = [
  "futures-io",
  "futures-util",
  "log",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "tungstenite 0.16.0",
 ]
 
@@ -455,6 +455,51 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
+[[package]]
+name = "axum"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f523b4e98ba6897ae90994bc18423d9877c54f9047b06a00ddc8122a957b1c70"
+dependencies = [
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes 1.0.1",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa 1.0.1",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite 0.2.8",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-http",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3ddbd16eabff8b45f21b98671fddcc93daaa7ac4c84f8473693437226040de5"
+dependencies = [
+ "async-trait",
+ "bytes 1.0.1",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+]
+
 [[package]]
 name = "backtrace"
 version = "0.3.64"
@@ -528,9 +573,9 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitvec"
@@ -877,6 +922,7 @@ dependencies = [
  "anyhow",
  "async-trait",
  "async-tungstenite",
+ "axum",
  "base64 0.13.0",
  "client",
  "collections",
@@ -886,7 +932,6 @@ dependencies = [
  "envy",
  "futures",
  "gpui",
- "hyper",
  "json_env_logger",
  "language",
  "lazy_static",
@@ -896,7 +941,6 @@ dependencies = [
  "parking_lot",
  "project",
  "rand 0.8.3",
- "routerify",
  "rpc",
  "scrypt",
  "serde",
@@ -1770,9 +1814,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.12"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1797,9 +1841,9 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.12"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
+checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
 
 [[package]]
 name = "futures-lite"
@@ -1812,17 +1856,16 @@ dependencies = [
  "futures-io",
  "memchr",
  "parking",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "waker-fn",
 ]
 
 [[package]]
 name = "futures-macro"
-version = "0.3.12"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
+checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
 dependencies = [
- "proc-macro-hack",
  "proc-macro2",
  "quote",
  "syn",
@@ -1830,21 +1873,21 @@ dependencies = [
 
 [[package]]
 name = "futures-sink"
-version = "0.3.14"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
 
 [[package]]
 name = "futures-task"
-version = "0.3.14"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
 
 [[package]]
 name = "futures-util"
-version = "0.3.12"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1853,10 +1896,8 @@ dependencies = [
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
  "slab",
 ]
 
@@ -2045,25 +2086,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "h2"
-version = "0.3.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
-dependencies = [
- "bytes 1.0.1",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
 [[package]]
 name = "hashbrown"
 version = "0.9.1"
@@ -2150,13 +2172,13 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.4"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
+checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
 dependencies = [
  "bytes 1.0.1",
  "fnv",
- "itoa 0.4.7",
+ "itoa 1.0.1",
 ]
 
 [[package]]
@@ -2176,7 +2198,7 @@ checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
 dependencies = [
  "bytes 1.0.1",
  "http",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
 ]
 
 [[package]]
@@ -2194,6 +2216,12 @@ dependencies = [
  "log",
 ]
 
+[[package]]
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
 [[package]]
 name = "http-types"
 version = "2.11.1"
@@ -2207,7 +2235,7 @@ dependencies = [
  "cookie",
  "futures-lite",
  "infer",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "rand 0.7.3",
  "serde",
  "serde_json",
@@ -2218,9 +2246,9 @@ dependencies = [
 
 [[package]]
 name = "httparse"
-version = "1.4.1"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
+checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba"
 
 [[package]]
 name = "httpdate"
@@ -2236,21 +2264,20 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.14.11"
+version = "0.14.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11"
+checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
 dependencies = [
  "bytes 1.0.1",
  "futures-channel",
  "futures-core",
  "futures-util",
- "h2",
  "http",
  "http-body",
  "httparse",
  "httpdate",
- "itoa 0.4.7",
- "pin-project-lite 0.2.4",
+ "itoa 1.0.1",
+ "pin-project-lite 0.2.8",
  "socket2 0.4.0",
  "tokio",
  "tower-service",
@@ -2723,6 +2750,12 @@ version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
+[[package]]
+name = "matchit"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
+
 [[package]]
 name = "maybe-uninit"
 version = "2.0.0"
@@ -3279,9 +3312,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.4"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
+checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
 
 [[package]]
 name = "pin-utils"
@@ -3403,12 +3436,6 @@ version = "0.5.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
-
 [[package]]
 name = "proc-macro2"
 version = "1.0.36"
@@ -3793,19 +3820,6 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
-[[package]]
-name = "routerify"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "496c1d3718081c45ba9c31fbfc07417900aa96f4070ff90dc29961836b7a9945"
-dependencies = [
- "http",
- "hyper",
- "lazy_static",
- "percent-encoding",
- "regex",
-]
-
 [[package]]
 name = "roxmltree"
 version = "0.14.1"
@@ -4679,7 +4693,7 @@ dependencies = [
  "log",
  "mime_guess",
  "once_cell",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "serde",
  "serde_json",
  "web-sys",
@@ -4731,6 +4745,12 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
 [[package]]
 name = "synstructure"
 version = "0.12.4"
@@ -5010,7 +5030,7 @@ dependencies = [
  "num_cpus",
  "once_cell",
  "parking_lot",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "signal-hook-registry",
  "tokio-macros",
  "winapi 0.3.9",
@@ -5048,9 +5068,8 @@ dependencies = [
  "bytes 1.0.1",
  "futures-core",
  "futures-sink",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "tokio",
- "tracing",
 ]
 
 [[package]]
@@ -5062,6 +5081,48 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "tower"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite 0.2.8",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8"
+dependencies = [
+ "bitflags",
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite 0.2.8",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
 [[package]]
 name = "tower-service"
 version = "0.3.1"
@@ -5076,7 +5137,7 @@ checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
 dependencies = [
  "cfg-if 1.0.0",
  "log",
- "pin-project-lite 0.2.4",
+ "pin-project-lite 0.2.8",
  "tracing-attributes",
  "tracing-core",
 ]

crates/collab/Cargo.toml 🔗

@@ -20,17 +20,16 @@ util = { path = "../util" }
 anyhow = "1.0.40"
 async-trait = "0.1.50"
 async-tungstenite = "0.16"
+axum = "0.5"
 base64 = "0.13"
 envy = "0.4.2"
 env_logger = "0.8"
 futures = "0.3"
-hyper = { version = "0.14", features = ["full"] }
 json_env_logger = "0.1"
 lipsum = { version = "0.8", optional = true }
 log = { version = "0.4.16", features = ["kv_unstable_serde"] }
 parking_lot = "0.11.1"
 rand = "0.8"
-routerify = "3.0"
 scrypt = "0.7"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"

crates/collab/src/api.rs 🔗

@@ -1,22 +1,20 @@
 // use crate::{auth, db::UserId, AppState, Request, RequestExt as _};
-use async_trait::async_trait;
-use hyper::{
-    header::{CONTENT_LENGTH, CONTENT_TYPE},
-    Body, Request, Response,
-};
-use routerify::prelude::*;
-
 use anyhow::Result;
-use routerify::RouterBuilder;
+use axum::{
+    body::Body,
+    http::{Request, Response, StatusCode},
+    routing::get,
+    Router,
+};
 use serde::Deserialize;
 use serde_json::json;
 use std::sync::Arc;
 
-use crate::{AppState, RequestExt};
+use crate::AppState;
 // use surf::StatusCode;
 
-pub fn add_routes(router: &mut RouterBuilder<Body, anyhow::Error>) {
-    router.get("/users", get_users);
+pub fn add_routes(router: Router<Body>) -> Router<Body> {
+    router.route("/users", get(get_users))
 }
 
 // pub fn add_routes(app: &mut tide::Server<Arc<AppState>>) {
@@ -29,6 +27,25 @@ pub fn add_routes(router: &mut RouterBuilder<Body, anyhow::Error>) {
 //         .post(create_access_token);
 // }
 
+async fn get_users(request: Request<Body>) -> Result<Response<Body>, (StatusCode, String)> {
+    // request.require_token().await?;
+
+    // let users = request.db().get_all_users().await?;
+
+    // Body::from
+
+    // let body = "Hello World";
+    // Ok(Response::builder()
+    //     .header(CONTENT_LENGTH, body.len() as u64)
+    //     .header(CONTENT_TYPE, "text/plain")
+    //     .body(Body::from(body))?)
+
+    // Ok(tide::Response::builder(StatusCode::Ok)
+    //     .body(tide::Body::from_json(&users)?)
+    //     .build())
+    todo!()
+}
+
 // async fn get_user(request: Request) -> tide::Result {
 //     request.require_token().await?;
 
@@ -43,24 +60,6 @@ pub fn add_routes(router: &mut RouterBuilder<Body, anyhow::Error>) {
 //         .build())
 // }
 
-async fn get_users(request: Request<Body>) -> Result<Response<Body>> {
-    // request.require_token().await?;
-
-    let users = request.db().get_all_users().await?;
-
-    // Body::from
-
-    let body = "Hello World";
-    Ok(Response::builder()
-        .header(CONTENT_LENGTH, body.len() as u64)
-        .header(CONTENT_TYPE, "text/plain")
-        .body(Body::from(body))?)
-
-    // Ok(tide::Response::builder(StatusCode::Ok)
-    //     .body(tide::Body::from_json(&users)?)
-    //     .build())
-}
-
 // async fn create_user(mut request: Request) -> tide::Result {
 //     request.require_token().await?;
 

crates/collab/src/main.rs 🔗

@@ -5,11 +5,10 @@ mod env;
 mod rpc;
 
 use ::rpc::Peer;
-use anyhow::{anyhow, Result};
+use anyhow::Result;
+use axum::{body::Body, http::StatusCode, Router};
 use db::{Db, PostgresDb};
-use hyper::{Body, Request, Server};
-use routerify::ext::RequestExt as _;
-use routerify::{Router, RouterService};
+
 use serde::Deserialize;
 use std::{net::TcpListener, sync::Arc};
 
@@ -39,15 +38,15 @@ impl AppState {
     }
 }
 
-trait RequestExt {
-    fn db(&self) -> &Arc<dyn Db>;
-}
+// trait RequestExt {
+//     fn db(&self) -> &Arc<dyn Db>;
+// }
 
-impl RequestExt for Request<Body> {
-    fn db(&self) -> &Arc<dyn Db> {
-        &self.data::<Arc<AppState>>().unwrap().db
-    }
-}
+// impl RequestExt for Request<Body> {
+//     fn db(&self) -> &Arc<dyn Db> {
+//         &self.data::<Arc<AppState>>().unwrap().db
+//     }
+// }
 
 #[tokio::main]
 async fn main() -> Result<()> {
@@ -77,10 +76,11 @@ async fn main() -> Result<()> {
     Ok(())
 }
 
-fn router(state: Arc<AppState>, peer: Arc<Peer>) -> Result<Router<Body, anyhow::Error>> {
-    let mut router = Router::builder().data(state);
-    api::add_routes(&mut router);
-    router.build().map_err(|error| anyhow!(error))
+async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {
+    (
+        StatusCode::INTERNAL_SERVER_ERROR,
+        format!("Something went wrong: {}", err),
+    )
 }
 
 pub async fn run_server(
@@ -88,19 +88,17 @@ pub async fn run_server(
     peer: Arc<Peer>,
     listener: TcpListener,
 ) -> Result<()> {
-    let service = RouterService::new(router(state, peer)?).map_err(|error| anyhow!(error))?;
-    Server::from_tcp(listener)?.serve(service);
-
-    // let mut app = tide::with_state(state.clone());
-    // rpc::add_routes(&mut app, &rpc);
-
-    // let mut web = tide::with_state(state.clone());
-    // web.with(CompressMiddleware::new());
-    // api::add_routes(&mut web);
+    let app = Router::<Body>::new();
+    // TODO: Assign app state to request somehow
+    // TODO: Compression on API routes?
+    // TODO: Authenticate API routes.
 
-    // app.at("/").nest(web);
+    let app = api::add_routes(app);
+    // TODO: Add rpc routes
 
-    // app.listen(listener).await?;
+    axum::Server::from_tcp(listener)?
+        .serve(app.into_make_service())
+        .await?;
 
     Ok(())
 }