diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02a6af3ee..942cc7f33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - rust_version: [stable, "1.43.1"] + rust_version: [stable, "1.46.0"] steps: - uses: actions/checkout@v1 diff --git a/Cargo.lock b/Cargo.lock index b5539c7a5..5ed75c8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,6 +205,12 @@ dependencies = [ "iovec", ] +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + [[package]] name = "cast" version = "0.2.7" @@ -710,16 +716,110 @@ version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" +[[package]] +name = "futures" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" + [[package]] name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures", + "futures 0.1.31", "num_cpus", ] +[[package]] +name = "futures-executor" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" + +[[package]] +name = "futures-macro" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +dependencies = [ + "autocfg 1.0.1", + "proc-macro-hack", + "proc-macro2 1.0.28", + "quote 1.0.9", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" + +[[package]] +name = "futures-task" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" + +[[package]] +name = "futures-util" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +dependencies = [ + "autocfg 1.0.1", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + [[package]] name = "generic-array" version = "0.12.4" @@ -777,10 +877,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" dependencies = [ "byteorder", - "bytes", + "bytes 0.4.12", "fnv", - "futures", - "http", + "futures 0.1.31", + "http 0.1.21", "indexmap", "log", "slab", @@ -830,7 +930,18 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" dependencies = [ - "bytes", + "bytes 0.4.12", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +dependencies = [ + "bytes 1.0.1", "fnv", "itoa", ] @@ -841,18 +952,35 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ - "bytes", - "futures", - "http", + "bytes 0.4.12", + "futures 0.1.31", + "http 0.1.21", "tokio-buf", ] +[[package]] +name = "http-body" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" +dependencies = [ + "bytes 1.0.1", + "http 0.2.4", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" +[[package]] +name = "httpdate" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" + [[package]] name = "humantime" version = "2.1.0" @@ -865,12 +993,12 @@ version = "0.12.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" dependencies = [ - "bytes", - "futures", + "bytes 0.4.12", + "futures 0.1.31", "futures-cpupool", "h2", - "http", - "http-body", + "http 0.1.21", + "http-body 0.1.0", "httparse", "iovec", "itoa", @@ -878,7 +1006,7 @@ dependencies = [ "net2", "rustc_version 0.2.3", "time", - "tokio", + "tokio 0.1.22", "tokio-buf", "tokio-executor", "tokio-io", @@ -886,7 +1014,30 @@ dependencies = [ "tokio-tcp", "tokio-threadpool", "tokio-timer", - "want", + "want 0.2.0", +] + +[[package]] +name = "hyper" +version = "0.14.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +dependencies = [ + "bytes 1.0.1", + "futures-channel", + "futures-core", + "futures-util", + "http 0.2.4", + "http-body 0.4.2", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio 1.9.0", + "tower-service", + "tracing", + "want 0.3.0", ] [[package]] @@ -895,9 +1046,9 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" dependencies = [ - "bytes", - "futures", - "hyper", + "bytes 0.4.12", + "futures 0.1.31", + "hyper 0.12.36", "native-tls", "tokio-io", ] @@ -1173,33 +1324,35 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow", + "miow 0.2.2", "net2", "slab", "winapi 0.2.8", ] [[package]] -name = "mio-extras" -version = "2.0.6" +name = "mio" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ - "lazycell", + "libc", "log", - "mio", - "slab", + "miow 0.3.7", + "ntapi", + "winapi 0.3.9", ] [[package]] -name = "mio-uds" -version = "0.6.8" +name = "mio-extras" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ - "iovec", - "libc", - "mio", + "lazycell", + "log", + "mio 0.6.23", + "slab", ] [[package]] @@ -1214,6 +1367,15 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "native-tls" version = "0.2.7" @@ -1255,12 +1417,21 @@ dependencies = [ "fsevent-sys", "inotify", "libc", - "mio", + "mio 0.6.23", "mio-extras", "walkdir", "winapi 0.3.9", ] +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -1446,6 +1617,18 @@ dependencies = [ "sha-1", ] +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.19" @@ -1939,14 +2122,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" dependencies = [ "base64 0.10.1", - "bytes", + "bytes 0.4.12", "cookie", "cookie_store", "encoding_rs", "flate2", - "futures", - "http", - "hyper", + "futures 0.1.31", + "http 0.1.21", + "hyper 0.12.36", "hyper-tls", "log", "mime", @@ -1956,7 +2139,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "time", - "tokio", + "tokio 0.1.22", "tokio-executor", "tokio-io", "tokio-threadpool", @@ -2047,10 +2230,10 @@ dependencies = [ "csv", "env_logger", "fs-err", - "futures", + "futures 0.3.16", "globset", "humantime", - "hyper", + "hyper 0.14.11", "insta", "jod-thread", "lazy_static", @@ -2079,7 +2262,7 @@ dependencies = [ "tempfile", "termcolor", "thiserror", - "tokio", + "tokio 1.9.0", "uuid 0.8.2", "walkdir", "winreg 0.9.0", @@ -2299,13 +2482,23 @@ dependencies = [ "proc-macro2 0.4.30", ] +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "string" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" dependencies = [ - "bytes", + "bytes 0.4.12", ] [[package]] @@ -2470,44 +2663,42 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ - "bytes", - "futures", - "mio", + "bytes 0.4.12", + "futures 0.1.31", + "mio 0.6.23", "num_cpus", - "tokio-codec", "tokio-current-thread", "tokio-executor", - "tokio-fs", "tokio-io", "tokio-reactor", - "tokio-sync", "tokio-tcp", "tokio-threadpool", "tokio-timer", - "tokio-udp", - "tokio-uds", ] [[package]] -name = "tokio-buf" -version = "0.1.1" +name = "tokio" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" dependencies = [ - "bytes", - "either", - "futures", + "autocfg 1.0.1", + "libc", + "mio 0.7.13", + "num_cpus", + "pin-project-lite", + "winapi 0.3.9", ] [[package]] -name = "tokio-codec" -version = "0.1.2" +name = "tokio-buf" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ - "bytes", - "futures", - "tokio-io", + "bytes 0.4.12", + "either", + "futures 0.1.31", ] [[package]] @@ -2516,7 +2707,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ - "futures", + "futures 0.1.31", "tokio-executor", ] @@ -2527,18 +2718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ "crossbeam-utils 0.7.2", - "futures", -] - -[[package]] -name = "tokio-fs" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" -dependencies = [ - "futures", - "tokio-io", - "tokio-threadpool", + "futures 0.1.31", ] [[package]] @@ -2547,8 +2727,8 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ - "bytes", - "futures", + "bytes 0.4.12", + "futures 0.1.31", "log", ] @@ -2559,10 +2739,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ "crossbeam-utils 0.7.2", - "futures", + "futures 0.1.31", "lazy_static", "log", - "mio", + "mio 0.6.23", "num_cpus", "parking_lot", "slab", @@ -2578,7 +2758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", - "futures", + "futures 0.1.31", ] [[package]] @@ -2587,10 +2767,10 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ - "bytes", - "futures", + "bytes 0.4.12", + "futures 0.1.31", "iovec", - "mio", + "mio 0.6.23", "tokio-io", "tokio-reactor", ] @@ -2604,7 +2784,7 @@ dependencies = [ "crossbeam-deque 0.7.3", "crossbeam-queue", "crossbeam-utils 0.7.2", - "futures", + "futures 0.1.31", "lazy_static", "log", "num_cpus", @@ -2619,42 +2799,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ "crossbeam-utils 0.7.2", - "futures", + "futures 0.1.31", "slab", "tokio-executor", ] [[package]] -name = "tokio-udp" -version = "0.1.6" +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ - "bytes", - "futures", - "log", - "mio", - "tokio-codec", - "tokio-io", - "tokio-reactor", + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", ] [[package]] -name = "tokio-uds" -version = "0.2.7" +name = "tracing-core" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" dependencies = [ - "bytes", - "futures", - "iovec", - "libc", - "log", - "mio", - "mio-uds", - "tokio-codec", - "tokio-io", - "tokio-reactor", + "lazy_static", ] [[package]] @@ -2812,7 +2985,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ - "futures", + "futures 0.1.31", + "log", + "try-lock", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ "log", "try-lock", ] diff --git a/Cargo.toml b/Cargo.toml index 61af26a9b..2efbe8478 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,10 +67,10 @@ crossbeam-channel = "0.5.1" csv = "1.1.1" env_logger = "0.9.0" fs-err = "2.2.0" -futures = "0.1.29" +futures = "0.3.16" globset = "0.4.4" humantime = "2.1.0" -hyper = "0.12.35" +hyper = { version = "0.14.11", features = ["server", "tcp", "http1"] } jod-thread = "0.1.0" lazy_static = "1.4.0" log = "0.4.8" @@ -87,7 +87,7 @@ serde_json = "1.0" structopt = "0.3.5" termcolor = "1.0.5" thiserror = "1.0.11" -tokio = "0.1.22" +tokio = { version = "1.9.0", features = ["rt", "rt-multi-thread"] } uuid = { version = "0.8.1", features = ["v4", "serde"] } [target.'cfg(windows)'.dependencies] diff --git a/README.md b/README.md index edf892583..ce0d5c309 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,13 @@
- - Rojo - + Rojo
 
- - Actions status - - - Latest server version - - - Rojo Documentation - + Actions status + Latest server version + Rojo Documentation

@@ -48,7 +40,7 @@ Check out our [contribution guide](CONTRIBUTING.md) for detailed instructions fo Pull requests are welcome! -Rojo supports Rust 1.43.1 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has. +Rojo supports Rust 1.46.0 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has. ## License Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details. \ No newline at end of file diff --git a/src/cli/build.rs b/src/cli/build.rs index 18798037f..38273f82f 100644 --- a/src/cli/build.rs +++ b/src/cli/build.rs @@ -50,7 +50,7 @@ impl BuildCommand { write_model(&session, &self.output, output_kind)?; if self.watch { - let mut rt = Runtime::new().unwrap(); + let rt = Runtime::new().unwrap(); loop { let receiver = session.message_queue().subscribe(cursor); diff --git a/src/message_queue.rs b/src/message_queue.rs index 13c18ce44..cbac18621 100644 --- a/src/message_queue.rs +++ b/src/message_queue.rs @@ -1,6 +1,6 @@ use std::sync::{Mutex, RwLock}; -use futures::sync::oneshot; +use futures::channel::oneshot; /// A message queue with persistent history that can be subscribed to. /// diff --git a/src/web/api.rs b/src/web/api.rs index 4038943a7..97624c7ef 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -3,9 +3,7 @@ use std::{collections::HashMap, fs, path::PathBuf, str::FromStr, sync::Arc}; -use futures::{Future, Stream}; - -use hyper::{service::Service, Body, Method, Request, StatusCode}; +use hyper::{body, Body, Method, Request, Response, StatusCode}; use rbx_dom_weak::types::Ref; use crate::{ @@ -21,45 +19,41 @@ use crate::{ }, }; -pub struct ApiService { - serve_session: Arc, -} +pub async fn call(serve_session: Arc, request: Request) -> Response { + let service = ApiService::new(serve_session); -impl Service for ApiService { - type ReqBody = Body; - type ResBody = Body; - type Error = hyper::Error; - type Future = - Box, Error = Self::Error> + Send>; - - fn call(&mut self, request: hyper::Request) -> Self::Future { - match (request.method(), request.uri().path()) { - (&Method::GET, "/api/rojo") => self.handle_api_rojo(), - (&Method::GET, path) if path.starts_with("/api/read/") => self.handle_api_read(request), - (&Method::GET, path) if path.starts_with("/api/subscribe/") => { - self.handle_api_subscribe(request) - } - (&Method::POST, path) if path.starts_with("/api/open/") => { - self.handle_api_open(request) - } + match (request.method(), request.uri().path()) { + (&Method::GET, "/api/rojo") => service.handle_api_rojo().await, + (&Method::GET, path) if path.starts_with("/api/read/") => { + service.handle_api_read(request).await + } + (&Method::GET, path) if path.starts_with("/api/subscribe/") => { + service.handle_api_subscribe(request).await + } + (&Method::POST, path) if path.starts_with("/api/open/") => { + service.handle_api_open(request).await + } - (&Method::POST, "/api/write") => self.handle_api_write(request), + (&Method::POST, "/api/write") => service.handle_api_write(request).await, - (_method, path) => json( - ErrorResponse::not_found(format!("Route not found: {}", path)), - StatusCode::NOT_FOUND, - ), - } + (_method, path) => json( + ErrorResponse::not_found(format!("Route not found: {}", path)), + StatusCode::NOT_FOUND, + ), } } +pub struct ApiService { + serve_session: Arc, +} + impl ApiService { pub fn new(serve_session: Arc) -> Self { ApiService { serve_session } } /// Get a summary of information about the server - fn handle_api_rojo(&self) -> ::Future { + async fn handle_api_rojo(&self) -> Response { let tree = self.serve_session.tree(); let root_instance_id = tree.get_root_id(); @@ -77,7 +71,7 @@ impl ApiService { /// Retrieve any messages past the given cursor index, and if /// there weren't any, subscribe to receive any new messages. - fn handle_api_subscribe(&self, request: Request) -> ::Future { + async fn handle_api_subscribe(&self, request: Request) -> Response { let argument = &request.uri().path()["/api/subscribe/".len()..]; let input_cursor: u32 = match argument.parse() { Ok(v) => v, @@ -91,11 +85,15 @@ impl ApiService { let session_id = self.serve_session.session_id(); - let receiver = self.serve_session.message_queue().subscribe(input_cursor); + let result = self + .serve_session + .message_queue() + .subscribe(input_cursor) + .await; let tree_handle = self.serve_session.tree_handle(); - Box::new(receiver.then(move |result| match result { + match result { Ok((message_cursor, messages)) => { let tree = tree_handle.lock().unwrap(); @@ -151,56 +149,56 @@ impl ApiService { ErrorResponse::internal_error("Message queue disconnected sender"), StatusCode::INTERNAL_SERVER_ERROR, ), - })) + } } - fn handle_api_write(&self, request: Request) -> ::Future { + async fn handle_api_write(&self, request: Request) -> Response { let session_id = self.serve_session.session_id(); let tree_mutation_sender = self.serve_session.tree_mutation_sender(); - Box::new(request.into_body().concat2().and_then(move |body| { - let request: WriteRequest = match serde_json::from_slice(&body) { - Ok(request) => request, - Err(err) => { - return json( - ErrorResponse::bad_request(format!("Invalid body: {}", err)), - StatusCode::BAD_REQUEST, - ); - } - }; + let body = body::to_bytes(request.into_body()).await.unwrap(); - if request.session_id != session_id { + let request: WriteRequest = match serde_json::from_slice(&body) { + Ok(request) => request, + Err(err) => { return json( - ErrorResponse::bad_request("Wrong session ID"), + ErrorResponse::bad_request(format!("Invalid body: {}", err)), StatusCode::BAD_REQUEST, ); } + }; - let updated_instances = request - .updated - .into_iter() - .map(|update| PatchUpdate { - id: update.id, - changed_class_name: update.changed_class_name, - changed_name: update.changed_name, - changed_properties: update.changed_properties, - changed_metadata: None, - }) - .collect(); - - tree_mutation_sender - .send(PatchSet { - removed_instances: Vec::new(), - added_instances: Vec::new(), - updated_instances, - }) - .unwrap(); + if request.session_id != session_id { + return json( + ErrorResponse::bad_request("Wrong session ID"), + StatusCode::BAD_REQUEST, + ); + } - json_ok(&WriteResponse { session_id }) - })) + let updated_instances = request + .updated + .into_iter() + .map(|update| PatchUpdate { + id: update.id, + changed_class_name: update.changed_class_name, + changed_name: update.changed_name, + changed_properties: update.changed_properties, + changed_metadata: None, + }) + .collect(); + + tree_mutation_sender + .send(PatchSet { + removed_instances: Vec::new(), + added_instances: Vec::new(), + updated_instances, + }) + .unwrap(); + + json_ok(&WriteResponse { session_id }) } - fn handle_api_read(&self, request: Request) -> ::Future { + async fn handle_api_read(&self, request: Request) -> Response { let argument = &request.uri().path()["/api/read/".len()..]; let requested_ids: Result, _> = argument.split(',').map(Ref::from_str).collect(); @@ -239,7 +237,7 @@ impl ApiService { } /// Open a script with the given ID in the user's default text editor. - fn handle_api_open(&self, request: Request) -> ::Future { + async fn handle_api_open(&self, request: Request) -> Response { let argument = &request.uri().path()["/api/open/".len()..]; let requested_id = match Ref::from_str(argument) { Ok(id) => id, diff --git a/src/web/mod.rs b/src/web/mod.rs index 5b3109f8c..d6df4b15d 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -8,50 +8,19 @@ pub mod interface; mod ui; mod util; -use std::{net::SocketAddr, sync::Arc}; - -use futures::{ - future::{self, FutureResult}, - Future, +use std::convert::Infallible; +use std::net::SocketAddr; +use std::sync::Arc; + +use hyper::{ + server::Server, + service::{make_service_fn, service_fn}, + Body, Request, }; -use hyper::{service::Service, Body, Request, Response, Server}; -use log::trace; +use tokio::runtime::Runtime; use crate::serve_session::ServeSession; -use self::{api::ApiService, ui::UiService}; - -pub struct RootService { - api: ApiService, - ui: UiService, -} - -impl Service for RootService { - type ReqBody = Body; - type ResBody = Body; - type Error = hyper::Error; - type Future = Box, Error = Self::Error> + Send>; - - fn call(&mut self, request: Request) -> Self::Future { - trace!("{} {}", request.method(), request.uri().path()); - - if request.uri().path().starts_with("/api") { - self.api.call(request) - } else { - self.ui.call(request) - } - } -} - -impl RootService { - pub fn new(serve_session: Arc) -> Self { - RootService { - api: ApiService::new(Arc::clone(&serve_session)), - ui: UiService::new(Arc::clone(&serve_session)), - } - } -} - pub struct LiveServer { serve_session: Arc, } @@ -62,14 +31,31 @@ impl LiveServer { } pub fn start(self, address: SocketAddr) { - let server = Server::bind(&address) - .serve(move || { - let service: FutureResult<_, hyper::Error> = - future::ok(RootService::new(Arc::clone(&self.serve_session))); - service - }) - .map_err(|e| eprintln!("Server error: {}", e)); - - hyper::rt::run(server); + let serve_session = Arc::clone(&self.serve_session); + + let make_service = make_service_fn(move |_conn| { + let serve_session = Arc::clone(&serve_session); + + async { + let service = move |req: Request| { + let serve_session = Arc::clone(&serve_session); + + async move { + if req.uri().path().starts_with("/api") { + Ok::<_, Infallible>(api::call(serve_session, req).await) + } else { + Ok::<_, Infallible>(ui::call(serve_session, req).await) + } + } + }; + + Ok::<_, Infallible>(service_fn(service)) + } + }); + + let rt = Runtime::new().unwrap(); + let _guard = rt.enter(); + let server = Server::bind(&address).serve(make_service); + rt.block_on(server).unwrap(); } } diff --git a/src/web/ui.rs b/src/web/ui.rs index 6ace230c8..0199d58d7 100644 --- a/src/web/ui.rs +++ b/src/web/ui.rs @@ -6,8 +6,7 @@ use std::{borrow::Cow, sync::Arc, time::Duration}; -use futures::{future, Future}; -use hyper::{header, service::Service, Body, Method, Request, Response, StatusCode}; +use hyper::{header, Body, Method, Request, Response, StatusCode}; use maplit::hashmap; use rbx_dom_weak::types::{Ref, Variant}; use ritz::{html, Fragment, HtmlContent, HtmlSelfClosingTag}; @@ -22,32 +21,23 @@ use crate::{ }, }; -pub struct UiService { - serve_session: Arc, +pub async fn call(serve_session: Arc, request: Request) -> Response { + let service = UiService::new(serve_session); + + match (request.method(), request.uri().path()) { + (&Method::GET, "/") => service.handle_home(), + (&Method::GET, "/logo.png") => service.handle_logo(), + (&Method::GET, "/icon.png") => service.handle_icon(), + (&Method::GET, "/show-instances") => service.handle_show_instances(), + (_method, path) => json( + ErrorResponse::not_found(format!("Route not found: {}", path)), + StatusCode::NOT_FOUND, + ), + } } -impl Service for UiService { - type ReqBody = Body; - type ResBody = Body; - type Error = hyper::Error; - type Future = Box, Error = Self::Error> + Send>; - - fn call(&mut self, request: Request) -> Self::Future { - let response = match (request.method(), request.uri().path()) { - (&Method::GET, "/") => self.handle_home(), - (&Method::GET, "/logo.png") => self.handle_logo(), - (&Method::GET, "/icon.png") => self.handle_icon(), - (&Method::GET, "/show-instances") => self.handle_show_instances(), - (_method, path) => { - return json( - ErrorResponse::not_found(format!("Route not found: {}", path)), - StatusCode::NOT_FOUND, - ) - } - }; - - Box::new(future::ok(response)) - } +pub struct UiService { + serve_session: Arc, } impl UiService { diff --git a/src/web/util.rs b/src/web/util.rs index 26ddec612..2b6882e5a 100644 --- a/src/web/util.rs +++ b/src/web/util.rs @@ -1,23 +1,11 @@ -use futures::{future, Future}; use hyper::{header::CONTENT_TYPE, Body, Response, StatusCode}; use serde::Serialize; -/// Respond to a request with JSON and the given status code. -pub fn json( - value: T, - code: StatusCode, -) -> Box, Error = hyper::Error> + Send> { - Box::new(future::ok(response_json(value, code))) -} - -/// Respond to a request with a 200 OK response containing JSON. -pub fn json_ok( - value: T, -) -> Box, Error = hyper::Error> + Send> { +pub fn json_ok(value: T) -> Response { json(value, StatusCode::OK) } -fn response_json(value: T, code: StatusCode) -> Response { +pub fn json(value: T, code: StatusCode) -> Response { let serialized = match serde_json::to_string(&value) { Ok(v) => v, Err(err) => {