├── .github └── workflows │ └── ci.yml ├── .gitignore ├── Makefile ├── README.md ├── book.toml ├── ci └── install-mdbook.sh ├── examples ├── 01_02_why_async │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 01_04_async_await_primer │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 01_05_http_server │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 02_02_future_trait │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 02_03_timer │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 02_04_executor │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 03_01_async_await │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 05_01_streams │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 05_02_iteration_and_concurrency │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 06_02_join │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 06_03_select │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── 07_05_recursion │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── Cargo.lock └── Cargo.toml ├── rust-toolchain └── src ├── 01_getting_started ├── 01_chapter.md ├── 02_why_async.md ├── 03_state_of_async_rust.md ├── 04_async_await_primer.md └── 05_http_server_example.md ├── 02_execution ├── 01_chapter.md ├── 02_future.md ├── 03_wakeups.md ├── 04_executor.md └── 05_io.md ├── 03_async_await └── 01_chapter.md ├── 04_pinning └── 01_chapter.md ├── 05_streams ├── 01_chapter.md └── 02_iteration_and_concurrency.md ├── 06_multiple_futures ├── 01_chapter.md ├── 02_join.md └── 03_select.md ├── 07_workarounds ├── 01_chapter.md ├── 02_return_type.md ├── 03_err_in_async_blocks.md ├── 04_send_approximation.md ├── 05_recursion.md └── 06_async_in_traits.md ├── 404.md ├── SUMMARY.md └── chapter_1.md /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | 3 | jobs: 4 | ci: 5 | name: CI 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@master 9 | 10 | - name: Rust version 11 | run: | 12 | rustc -vV 13 | cargo -vV 14 | 15 | - name: Setup 16 | run: test -x $HOME/.cargo/bin/mdbook || ./ci/install-mdbook.sh 17 | 18 | - name: mdbook build 19 | run: mdbook build 20 | 21 | - name: examples code test 22 | run: cargo test --all --manifest-path=./examples/Cargo.toml --target-dir ./target 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | @test -x ${HOME}/.cargo/bin/mdbook || ./ci/install-mdbook.sh 4 | @mdbook build 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Asynchronous Programming in Rust 2 | [![Netlify Status](https://api.netlify.com/api/v1/badges/5c2ad47e-f528-40b1-a927-fef6fe05db16/deploy-status)](https://app.netlify.com/sites/async-book-ja/deploys) 3 | 4 | [Rust async-book](https://rust-lang.github.io/async-book) の和訳リポジトリ 5 | 6 | 訳者は英語が全く分かっていないためなるべく本家を読んだほうが良いです。 7 | 誤訳だらけです。 8 | 9 | あと、コード中のコメント文の翻訳は後回しにします 10 | 11 | サイトは[こちら](https://async-book-ja.netlify.com) 12 | 13 | ## Build 14 | 15 | ``` 16 | cargo install mdbook 17 | mdbook serve 18 | ``` 19 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["k-nasa"] 3 | language = "ja" 4 | multilingual = false 5 | src = "src" 6 | title = "Asynchronous Programming in Rust" 7 | 8 | [build] 9 | create-missing = false 10 | 11 | [preprocess.links] 12 | 13 | [output.html] 14 | git-repository-url = "https://github.com/k-nasa/async-book-ja" 15 | git-repository-icon = "fa-github" 16 | -------------------------------------------------------------------------------- /ci/install-mdbook.sh: -------------------------------------------------------------------------------- 1 | set -euxo pipefail 2 | 3 | # Based on the Rust-Embedded WG's book CI 4 | # https://github.com/rust-embedded/book/blob/master/ci/install.sh 5 | 6 | main() { 7 | # Note - this will only accept releases tagged with v0.3.x 8 | local tag=$(git ls-remote --tags --refs --exit-code \ 9 | https://github.com/rust-lang-nursery/mdbook \ 10 | | cut -d/ -f3 \ 11 | | grep -E '^v0\.3\.[0-9]+$' \ 12 | | sort --version-sort \ 13 | | tail -n1) 14 | 15 | curl -LSfs https://japaric.github.io/trust/install.sh | \ 16 | sh -s -- --git rust-lang-nursery/mdbook --tag $tag 17 | } 18 | 19 | main 20 | -------------------------------------------------------------------------------- /examples/01_02_why_async/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "01_02_why_async" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/01_02_why_async/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | use { 4 | futures::{ 5 | executor::block_on, 6 | join, 7 | }, 8 | std::thread, 9 | }; 10 | 11 | fn download(_url: &str) { 12 | // ... 13 | } 14 | 15 | #[test] 16 | // ANCHOR: get_two_sites 17 | fn get_two_sites() { 18 | // 作業を行うために2つのスレッドを作成します。 19 | let thread_one = thread::spawn(|| download("https:://www.foo.com")); 20 | let thread_two = thread::spawn(|| download("https:://www.bar.com")); 21 | 22 | // 両方のスレッドが完了するまで待ちます。 23 | thread_one.join().expect("thread one panicked"); 24 | thread_two.join().expect("thread two panicked"); 25 | } 26 | // ANCHOR_END: get_two_sites 27 | 28 | async fn download_async(_url: &str) { 29 | // ... 30 | } 31 | 32 | // ANCHOR: get_two_sites_async 33 | async fn get_two_sites_async() { 34 | // 2つの異なるfutureを作成します。これらは、完了するまで実行すると 35 | // 非同期でWebページをダウンロードします。 36 | let future_one = download_async("https:://www.foo.com"); 37 | let future_two = download_async("https:://www.bar.com"); 38 | 39 | // 両方のfutureを同時に完了するまで実行します。 40 | join!(future_one, future_two); 41 | } 42 | // ANCHOR_END: get_two_sites_async 43 | 44 | #[test] 45 | fn get_two_sites_async_test() { 46 | block_on(get_two_sites_async()); 47 | } 48 | -------------------------------------------------------------------------------- /examples/01_04_async_await_primer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "01_04_async_await_primer" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/01_04_async_await_primer/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | use futures::executor::block_on; 4 | 5 | mod first { 6 | // ANCHOR: hello_world 7 | // block_onは提供されたfutureが完了するまで現在のスレッドをブロックします。 8 | // 他のエグゼキューターは、同じスレッドに複数のfutureをスケジュールするなど、 9 | // より複雑な動作を提供します。 10 | use futures::executor::block_on; 11 | 12 | async fn hello_world() { 13 | println!("hello, world!"); 14 | } 15 | 16 | fn main() { 17 | let future = hello_world(); // ここでは何もprintされない 18 | block_on(future); // futureが動き"hello, world!"が表示される 19 | } 20 | // ANCHOR_END: hello_world 21 | 22 | #[test] 23 | fn run_main() { main() } 24 | } 25 | 26 | struct Song; 27 | async fn learn_song() -> Song { Song } 28 | async fn sing_song(_: Song) {} 29 | async fn dance() {} 30 | 31 | mod second { 32 | use super::*; 33 | // ANCHOR: block_on_each 34 | fn main() { 35 | let song = block_on(learn_song()); 36 | block_on(sing_song(song)); 37 | block_on(dance()); 38 | } 39 | // ANCHOR_END: block_on_each 40 | 41 | #[test] 42 | fn run_main() { main() } 43 | } 44 | 45 | mod third { 46 | use super::*; 47 | // ANCHOR: block_on_main 48 | async fn learn_and_sing() { 49 | // Wait until the song has been learned before singing it. 50 | // We use `.await` here rather than `block_on` to prevent blocking the 51 | // thread, which makes it possible to `dance` at the same time. 52 | let song = learn_song().await; 53 | sing_song(song).await; 54 | } 55 | 56 | async fn async_main() { 57 | let f1 = learn_and_sing(); 58 | let f2 = dance(); 59 | 60 | // `join!` is like `.await` but can wait for multiple futures concurrently. 61 | // If we're temporarily blocked in the `learn_and_sing` future, the `dance` 62 | // future will take over the current thread. If `dance` becomes blocked, 63 | // `learn_and_sing` can take back over. If both futures are blocked, then 64 | // `async_main` is blocked and will yield to the executor. 65 | futures::join!(f1, f2); 66 | } 67 | 68 | fn main() { 69 | block_on(async_main()); 70 | } 71 | // ANCHOR_END: block_on_main 72 | 73 | #[test] 74 | fn run_main() { main() } 75 | } 76 | -------------------------------------------------------------------------------- /examples/01_05_http_server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "01_05_http_server" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dependencies] 10 | # The latest version of the "futures" library, which has lots of utilities 11 | # for writing async code. Enable the "compat" feature to include the 12 | # functions for using futures 0.3 and async/await with the Hyper library, 13 | # which use futures 0.1. 14 | futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } 15 | 16 | # Hyper is an asynchronous HTTP library. We'll use it to power our HTTP 17 | # server and to make HTTP requests. 18 | hyper = "0.12.9" 19 | 20 | # (only for testing) 21 | failure = "0.1.5" 22 | reqwest = "0.9.18" 23 | -------------------------------------------------------------------------------- /examples/01_05_http_server/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | // ANCHOR: imports 4 | use { 5 | hyper::{ 6 | // Miscellaneous types from Hyper for working with HTTP. 7 | Body, Client, Request, Response, Server, Uri, 8 | 9 | // This function turns a closure which returns a future into an 10 | // implementation of the the Hyper `Service` trait, which is an 11 | // asynchronous function from a generic `Request` to a `Response`. 12 | service::service_fn, 13 | 14 | // A function which runs a future to completion using the Hyper runtime. 15 | rt::run, 16 | }, 17 | futures::{ 18 | // Extension trait for futures 0.1 futures, adding the `.compat()` method 19 | // which allows us to use `.await` on 0.1 futures. 20 | compat::Future01CompatExt, 21 | // Extension traits providing additional methods on futures. 22 | // `FutureExt` adds methods that work for all futures, whereas 23 | // `TryFutureExt` adds methods to futures that return `Result` types. 24 | future::{FutureExt, TryFutureExt}, 25 | }, 26 | std::net::SocketAddr, 27 | }; 28 | // ANCHOR_END: imports 29 | 30 | // ANCHOR: boilerplate 31 | async fn serve_req(_req: Request) -> Result, hyper::Error> { 32 | // Always return successfully with a response containing a body with 33 | // a friendly greeting ;) 34 | Ok(Response::new(Body::from("hello, world!"))) 35 | } 36 | 37 | async fn run_server(addr: SocketAddr) { 38 | println!("Listening on http://{}", addr); 39 | 40 | // Create a server bound on the provided address 41 | let serve_future = Server::bind(&addr) 42 | // Serve requests using our `async serve_req` function. 43 | // `serve` takes a closure which returns a type implementing the 44 | // `Service` trait. `service_fn` returns a value implementing the 45 | // `Service` trait, and accepts a closure which goes from request 46 | // to a future of the response. To use our `serve_req` function with 47 | // Hyper, we have to box it and put it in a compatability 48 | // wrapper to go from a futures 0.3 future (the kind returned by 49 | // `async fn`) to a futures 0.1 future (the kind used by Hyper). 50 | .serve(|| service_fn(|req| serve_req(req).boxed().compat())); 51 | 52 | // Wait for the server to complete serving or exit with an error. 53 | // If an error occurred, print it to stderr. 54 | if let Err(e) = serve_future.compat().await { 55 | eprintln!("server error: {}", e); 56 | } 57 | } 58 | 59 | fn main() { 60 | // Set the address to run our socket on. 61 | let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); 62 | 63 | // Call our `run_server` function, which returns a future. 64 | // As with every `async fn`, for `run_server` to do anything, 65 | // the returned future needs to be run. Additionally, 66 | // we need to convert the returned future from a futures 0.3 future into a 67 | // futures 0.1 future. 68 | let futures_03_future = run_server(addr); 69 | let futures_01_future = futures_03_future.unit_error().boxed().compat(); 70 | 71 | // Finally, we can run the future to completion using the `run` function 72 | // provided by Hyper. 73 | run(futures_01_future); 74 | } 75 | // ANCHOR_END: boilerplate 76 | 77 | #[test] 78 | fn run_main_and_query_http() -> Result<(), failure::Error> { 79 | std::thread::spawn(|| main()); 80 | // Unfortunately, there's no good way for us to detect when the server 81 | // has come up, so we sleep for an amount that should hopefully be 82 | // sufficient :( 83 | std::thread::sleep(std::time::Duration::from_secs(5)); 84 | let response = reqwest::get("http://localhost:3000")?.text()?; 85 | assert_eq!(response, "hello, world!"); 86 | Ok(()) 87 | } 88 | 89 | mod proxy { 90 | use super::*; 91 | #[allow(unused)] 92 | async fn serve_req(_req: Request) -> Result, hyper::Error> { 93 | // ANCHOR: parse_url 94 | let url_str = "http://www.rust-lang.org/en-US/"; 95 | let url = url_str.parse::().expect("failed to parse URL"); 96 | // ANCHOR_END: parse_url 97 | 98 | // ANCHOR: get_request 99 | let res = Client::new().get(url).compat().await; 100 | // Return the result of the request directly to the user 101 | println!("request finished-- returning response"); 102 | res 103 | // ANCHOR_END: get_request 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /examples/02_02_future_trait/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "02_02_future_trait" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | -------------------------------------------------------------------------------- /examples/02_02_future_trait/src/lib.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: simple_future 2 | trait SimpleFuture { 3 | type Output; 4 | fn poll(&mut self, wake: fn()) -> Poll; 5 | } 6 | 7 | enum Poll { 8 | Ready(T), 9 | Pending, 10 | } 11 | // ANCHOR_END: simple_future 12 | 13 | struct Socket; 14 | impl Socket { 15 | fn has_data_to_read(&self) -> bool { 16 | // check if the socket is currently readable 17 | true 18 | } 19 | fn read_buf(&self) -> Vec { 20 | // Read data in from the socket 21 | vec![] 22 | } 23 | fn set_readable_callback(&self, _wake: fn()) { 24 | // register `_wake` with something that will call it 25 | // once the socket becomes readable, such as an 26 | // `epoll`-based event loop. 27 | } 28 | } 29 | 30 | // ANCHOR: socket_read 31 | pub struct SocketRead<'a> { 32 | socket: &'a Socket, 33 | } 34 | 35 | impl SimpleFuture for SocketRead<'_> { 36 | type Output = Vec; 37 | 38 | fn poll(&mut self, wake: fn()) -> Poll { 39 | if self.socket.has_data_to_read() { 40 | // ソケットにはデータがあります。それをバッファに読み込んで返します。 41 | Poll::Ready(self.socket.read_buf()) 42 | } else { 43 | // ソケットにはまだデータがありません 44 | // 45 | // データが利用可能になったらwakeが呼び出されるようにします。 46 | // データが利用可能になるとwakeが呼び出され 47 | // このFutureのユーザーは再度pollを呼び出してデータを受信することが分かります。 48 | self.socket.set_readable_callback(wake); 49 | Poll::Pending 50 | } 51 | } 52 | } 53 | // ANCHOR_END: socket_read 54 | 55 | // ANCHOR: join 56 | /// A SimpleFuture that runs two other futures to completion concurrently. 57 | /// 58 | /// Concurrency is achieved via the fact that calls to `poll` each future 59 | /// may be interleaved, allowing each future to advance itself at its own pace. 60 | pub struct Join { 61 | // Each field may contain a future that should be run to completion. 62 | // If the future has already completed, the field is set to `None`. 63 | // This prevents us from polling a future after it has completed, which 64 | // would violate the contract of the `Future` trait. 65 | a: Option, 66 | b: Option, 67 | } 68 | 69 | impl SimpleFuture for Join 70 | where 71 | FutureA: SimpleFuture, 72 | FutureB: SimpleFuture, 73 | { 74 | type Output = (); 75 | fn poll(&mut self, wake: fn()) -> Poll { 76 | // Attempt to complete future `a`. 77 | if let Some(a) = &mut self.a { 78 | if let Poll::Ready(()) = a.poll(wake) { 79 | self.a.take(); 80 | } 81 | } 82 | 83 | // Attempt to complete future `b`. 84 | if let Some(b) = &mut self.b { 85 | if let Poll::Ready(()) = b.poll(wake) { 86 | self.b.take(); 87 | } 88 | } 89 | 90 | if self.a.is_none() && self.b.is_none() { 91 | // Both futures have completed-- we can return successfully 92 | Poll::Ready(()) 93 | } else { 94 | // One or both futures returned `Poll::Pending` and still have 95 | // work to do. They will call `wake()` when progress can be made. 96 | Poll::Pending 97 | } 98 | } 99 | } 100 | // ANCHOR_END: join 101 | 102 | // ANCHOR: and_then 103 | /// A SimpleFuture that runs two futures to completion, one after another. 104 | // 105 | // Note: for the purposes of this simple example, `AndThenFut` assumes both 106 | // the first and second futures are available at creation-time. The real 107 | // `AndThen` combinator allows creating the second future based on the output 108 | // of the first future, like `get_breakfast.and_then(|food| eat(food))`. 109 | pub struct AndThenFut { 110 | first: Option, 111 | second: FutureB, 112 | } 113 | 114 | impl SimpleFuture for AndThenFut 115 | where 116 | FutureA: SimpleFuture, 117 | FutureB: SimpleFuture, 118 | { 119 | type Output = (); 120 | fn poll(&mut self, wake: fn()) -> Poll { 121 | if let Some(first) = &mut self.first { 122 | match first.poll(wake) { 123 | // We've completed the first future-- remove it and start on 124 | // the second! 125 | Poll::Ready(()) => self.first.take(), 126 | // We couldn't yet complete the first future. 127 | Poll::Pending => return Poll::Pending, 128 | }; 129 | } 130 | // Now that the first future is done, attempt to complete the second. 131 | self.second.poll(wake) 132 | } 133 | } 134 | // ANCHOR_END: and_then 135 | 136 | mod real_future { 137 | use std::{ 138 | future::Future as RealFuture, 139 | pin::Pin, 140 | task::{Context, Poll}, 141 | }; 142 | 143 | // ANCHOR: real_future 144 | trait Future { 145 | type Output; 146 | fn poll( 147 | // Note the change from `&mut self` to `Pin<&mut Self>`: 148 | self: Pin<&mut Self>, 149 | // and the change from `wake: fn()` to `cx: &mut Context<'_>`: 150 | cx: &mut Context<'_>, 151 | ) -> Poll; 152 | } 153 | // ANCHOR_END: real_future 154 | 155 | // ensure that `Future` matches `RealFuture`: 156 | impl Future for dyn RealFuture { 157 | type Output = O; 158 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { 159 | RealFuture::poll(self, cx) 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /examples/02_03_timer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "02_03_timer" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/02_03_timer/src/lib.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: imports 2 | use { 3 | std::{ 4 | future::Future, 5 | pin::Pin, 6 | sync::{Arc, Mutex}, 7 | task::{Context, Poll, Waker}, 8 | thread, 9 | time::Duration, 10 | }, 11 | }; 12 | // ANCHOR_END: imports 13 | 14 | // ANCHOR: timer_decl 15 | pub struct TimerFuture { 16 | shared_state: Arc>, 17 | } 18 | 19 | /// Shared state between the future and the waiting thread 20 | struct SharedState { 21 | /// Whether or not the sleep time has elapsed 22 | completed: bool, 23 | 24 | /// The waker for the task that `TimerFuture` is running on. 25 | /// The thread can use this after setting `completed = true` to tell 26 | /// `TimerFuture`'s task to wake up, see that `completed = true`, and 27 | /// move forward. 28 | waker: Option, 29 | } 30 | // ANCHOR_END: timer_decl 31 | 32 | // ANCHOR: future_for_timer 33 | impl Future for TimerFuture { 34 | type Output = (); 35 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { 36 | // Look at the shared state to see if the timer has already completed. 37 | let mut shared_state = self.shared_state.lock().unwrap(); 38 | if shared_state.completed { 39 | Poll::Ready(()) 40 | } else { 41 | // Set waker so that the thread can wake up the current task 42 | // when the timer has completed, ensuring that the future is polled 43 | // again and sees that `completed = true`. 44 | // 45 | // It's tempting to do this once rather than repeatedly cloning 46 | // the waker each time. However, the `TimerFuture` can move between 47 | // tasks on the executor, which could cause a stale waker pointing 48 | // to the wrong task, preventing `TimerFuture` from waking up 49 | // correctly. 50 | // 51 | // N.B. it's possible to check for this using the `Waker::will_wake` 52 | // function, but we omit that here to keep things simple. 53 | shared_state.waker = Some(cx.waker().clone()); 54 | Poll::Pending 55 | } 56 | } 57 | } 58 | // ANCHOR_END: future_for_timer 59 | 60 | // ANCHOR: timer_new 61 | impl TimerFuture { 62 | /// Create a new `TimerFuture` which will complete after the provided 63 | /// timeout. 64 | pub fn new(duration: Duration) -> Self { 65 | let shared_state = Arc::new(Mutex::new(SharedState { 66 | completed: false, 67 | waker: None, 68 | })); 69 | 70 | // Spawn the new thread 71 | let thread_shared_state = shared_state.clone(); 72 | thread::spawn(move || { 73 | thread::sleep(duration); 74 | let mut shared_state = thread_shared_state.lock().unwrap(); 75 | // Signal that the timer has completed and wake up the last 76 | // task on which the future was polled, if one exists. 77 | shared_state.completed = true; 78 | if let Some(waker) = shared_state.waker.take() { 79 | waker.wake() 80 | } 81 | }); 82 | 83 | TimerFuture { shared_state } 84 | } 85 | } 86 | // ANCHOR_END: timer_new 87 | 88 | #[test] 89 | fn block_on_timer() { 90 | futures::executor::block_on(async { 91 | TimerFuture::new(Duration::from_secs(1)).await 92 | }) 93 | } 94 | -------------------------------------------------------------------------------- /examples/02_04_executor/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "02_04_executor" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17" } 11 | timer_future = { package = "02_03_timer", path = "../02_03_timer" } 12 | -------------------------------------------------------------------------------- /examples/02_04_executor/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | // ANCHOR: imports 4 | use { 5 | futures::{ 6 | future::{FutureExt, BoxFuture}, 7 | task::{ArcWake, waker_ref}, 8 | }, 9 | std::{ 10 | future::Future, 11 | sync::{Arc, Mutex}, 12 | sync::mpsc::{sync_channel, SyncSender, Receiver}, 13 | task::{Context, Poll}, 14 | time::Duration, 15 | }, 16 | // The timer we wrote in the previous section: 17 | timer_future::TimerFuture, 18 | }; 19 | // ANCHOR_END: imports 20 | 21 | // ANCHOR: executor_decl 22 | /// Task executor that receives tasks off of a channel and runs them. 23 | struct Executor { 24 | ready_queue: Receiver>, 25 | } 26 | 27 | /// `Spawner` spawns new futures onto the task channel. 28 | #[derive(Clone)] 29 | struct Spawner { 30 | task_sender: SyncSender>, 31 | } 32 | 33 | /// A future that can reschedule itself to be polled by an `Executor`. 34 | struct Task { 35 | /// In-progress future that should be pushed to completion. 36 | /// 37 | /// The `Mutex` is not necessary for correctness, since we only have 38 | /// one thread executing tasks at once. However, Rust isn't smart 39 | /// enough to know that `future` is only mutated from one thread, 40 | /// so we need use the `Mutex` to prove thread-safety. A production 41 | /// executor would not need this, and could use `UnsafeCell` instead. 42 | future: Mutex>>, 43 | 44 | /// Handle to place the task itself back onto the task queue. 45 | task_sender: SyncSender>, 46 | } 47 | 48 | fn new_executor_and_spawner() -> (Executor, Spawner) { 49 | // Maximum number of tasks to allow queueing in the channel at once. 50 | // This is just to make `sync_channel` happy, and wouldn't be present in 51 | // a real executor. 52 | const MAX_QUEUED_TASKS: usize = 10_000; 53 | let (task_sender, ready_queue) = sync_channel(MAX_QUEUED_TASKS); 54 | (Executor { ready_queue }, Spawner { task_sender}) 55 | } 56 | // ANCHOR_END: executor_decl 57 | 58 | // ANCHOR: spawn_fn 59 | impl Spawner { 60 | fn spawn(&self, future: impl Future + 'static + Send) { 61 | let future = future.boxed(); 62 | let task = Arc::new(Task { 63 | future: Mutex::new(Some(future)), 64 | task_sender: self.task_sender.clone(), 65 | }); 66 | self.task_sender.send(task).expect("too many tasks queued"); 67 | } 68 | } 69 | // ANCHOR_END: spawn_fn 70 | 71 | // ANCHOR: arcwake_for_task 72 | impl ArcWake for Task { 73 | fn wake_by_ref(arc_self: &Arc) { 74 | // Implement `wake` by sending this task back onto the task channel 75 | // so that it will be polled again by the executor. 76 | let cloned = arc_self.clone(); 77 | arc_self.task_sender.send(cloned).expect("too many tasks queued"); 78 | } 79 | } 80 | // ANCHOR_END: arcwake_for_task 81 | 82 | // ANCHOR: executor_run 83 | impl Executor { 84 | fn run(&self) { 85 | while let Ok(task) = self.ready_queue.recv() { 86 | // Take the future, and if it has not yet completed (is still Some), 87 | // poll it in an attempt to complete it. 88 | let mut future_slot = task.future.lock().unwrap(); 89 | if let Some(mut future) = future_slot.take() { 90 | // Create a `LocalWaker` from the task itself 91 | let waker = waker_ref(&task); 92 | let context = &mut Context::from_waker(&*waker); 93 | // `BoxFuture` is a type alias for 94 | // `Pin + Send + 'static>>`. 95 | // We can get a `Pin<&mut dyn Future + Send + 'static>` 96 | // from it by calling the `Pin::as_mut` method. 97 | if let Poll::Pending = future.as_mut().poll(context) { 98 | // We're not done processing the future, so put it 99 | // back in its task to be run again in the future. 100 | *future_slot = Some(future); 101 | } 102 | } 103 | } 104 | } 105 | } 106 | // ANCHOR_END: executor_run 107 | 108 | // ANCHOR: main 109 | fn main() { 110 | let (executor, spawner) = new_executor_and_spawner(); 111 | 112 | // Spawn a task to print before and after waiting on a timer. 113 | spawner.spawn(async { 114 | println!("howdy!"); 115 | // Wait for our timer future to complete after two seconds. 116 | TimerFuture::new(Duration::new(2, 0)).await; 117 | println!("done!"); 118 | }); 119 | 120 | // Drop the spawner so that our executor knows it is finished and won't 121 | // receive more incoming tasks to run. 122 | drop(spawner); 123 | 124 | // Run the executor until the task queue is empty. 125 | // This will print "howdy!", pause, and then print "done!". 126 | executor.run(); 127 | } 128 | // ANCHOR_END: main 129 | 130 | #[test] 131 | fn run_main() { main() } 132 | -------------------------------------------------------------------------------- /examples/03_01_async_await/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "03_01_async_await" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/03_01_async_await/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | #![cfg(test)] 3 | 4 | mod async_fn_and_block_examples { 5 | use std::future::Future; 6 | // ANCHOR: async_fn_and_block_examples 7 | 8 | // `foo()` returns a type that implements `Future`. 9 | // `foo().await` will result in a value of type `u8`. 10 | async fn foo() -> u8 { 5 } 11 | 12 | fn bar() -> impl Future { 13 | // This `async` block results in a type that implements 14 | // `Future`. 15 | async { 16 | let x: u8 = foo().await; 17 | x + 5 18 | } 19 | } 20 | // ANCHOR_END: async_fn_and_block_examples 21 | } 22 | 23 | mod async_lifetimes_examples { 24 | use std::future::Future; 25 | // ANCHOR: lifetimes_expanded 26 | // This function: 27 | async fn foo(x: &u8) -> u8 { *x } 28 | 29 | // Is equivalent to this function: 30 | fn foo_expanded<'a>(x: &'a u8) -> impl Future + 'a { 31 | async move { *x } 32 | } 33 | // ANCHOR_END: lifetimes_expanded 34 | 35 | async fn borrow_x(x: &u8) -> u8 { *x } 36 | 37 | #[cfg(feature = "never_compiled")] 38 | // ANCHOR: static_future_with_borrow 39 | fn bad() -> impl Future { 40 | let x = 5; 41 | borrow_x(&x) // ERROR: `x` does not live long enough 42 | } 43 | 44 | fn good() -> impl Future { 45 | async { 46 | let x = 5; 47 | borrow_x(&x).await 48 | } 49 | } 50 | // ANCHOR_END: static_future_with_borrow 51 | } 52 | 53 | mod async_move_examples { 54 | use std::future::Future; 55 | // ANCHOR: async_move_examples 56 | /// `async` block: 57 | /// 58 | /// Multiple different `async` blocks can access the same local variable 59 | /// so long as they're executed within the variable's scope 60 | async fn blocks() { 61 | let my_string = "foo".to_string(); 62 | 63 | let future_one = async { 64 | // ... 65 | println!("{}", my_string); 66 | }; 67 | 68 | let future_two = async { 69 | // ... 70 | println!("{}", my_string); 71 | }; 72 | 73 | // Run both futures to completion, printing "foo" twice: 74 | let ((), ()) = futures::join!(future_one, future_two); 75 | } 76 | 77 | /// `async move` block: 78 | /// 79 | /// Only one `async move` block can access the same captured variable, since 80 | /// captures are moved into the `Future` generated by the `async move` block. 81 | /// However, this allows the `Future` to outlive the original scope of the 82 | /// variable: 83 | fn move_block() -> impl Future { 84 | let my_string = "foo".to_string(); 85 | async move { 86 | // ... 87 | println!("{}", my_string); 88 | } 89 | } 90 | // ANCHOR_END: async_move_examples 91 | } 92 | -------------------------------------------------------------------------------- /examples/05_01_streams/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "05_01_streams" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/05_01_streams/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | mod stream_trait { 4 | use { 5 | futures::stream::{Stream as RealStream}, 6 | std::{ 7 | pin::Pin, 8 | task::{Context, Poll}, 9 | }, 10 | }; 11 | 12 | // ANCHOR: stream_trait 13 | trait Stream { 14 | /// The type of the value yielded by the stream. 15 | type Item; 16 | 17 | /// Attempt to resolve the next item in the stream. 18 | /// Retuns `Poll::Pending` if not ready, `Poll::Ready(Some(x))` if a value 19 | /// is ready, and `Poll::Ready(None)` if the stream has completed. 20 | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) 21 | -> Poll>; 22 | } 23 | // ANCHOR_END: stream_trait 24 | 25 | // assert that `Stream` matches `RealStream`: 26 | impl Stream for dyn RealStream { 27 | type Item = I; 28 | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) 29 | -> Poll> 30 | { 31 | RealStream::poll_next(self, cx) 32 | } 33 | } 34 | } 35 | 36 | mod channels { 37 | use { 38 | futures::{ 39 | channel::mpsc, 40 | prelude::*, 41 | }, 42 | }; 43 | 44 | // ANCHOR: channels 45 | async fn send_recv() { 46 | const BUFFER_SIZE: usize = 10; 47 | let (mut tx, mut rx) = mpsc::channel::(BUFFER_SIZE); 48 | 49 | tx.send(1).await.unwrap(); 50 | tx.send(2).await.unwrap(); 51 | drop(tx); 52 | 53 | // `StreamExt::next` is similar to `Iterator::next`, but returns a 54 | // type that implements `Future>`. 55 | assert_eq!(Some(1), rx.next().await); 56 | assert_eq!(Some(2), rx.next().await); 57 | assert_eq!(None, rx.next().await); 58 | } 59 | // ANCHOR_END: channels 60 | 61 | #[test] 62 | fn run_send_recv() { futures::executor::block_on(send_recv()) } 63 | } 64 | -------------------------------------------------------------------------------- /examples/05_02_iteration_and_concurrency/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "05_02_iteration_and_concurrency" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/05_02_iteration_and_concurrency/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | use { 4 | futures::{ 5 | executor::block_on, 6 | stream::{self, Stream}, 7 | }, 8 | std::{ 9 | io, 10 | pin::Pin, 11 | }, 12 | }; 13 | 14 | // ANCHOR: nexts 15 | async fn sum_with_next(mut stream: Pin<&mut dyn Stream>) -> i32 { 16 | use futures::stream::StreamExt; // for `next` 17 | let mut sum = 0; 18 | while let Some(item) = stream.next().await { 19 | sum += item; 20 | } 21 | sum 22 | } 23 | 24 | async fn sum_with_try_next( 25 | mut stream: Pin<&mut dyn Stream>>, 26 | ) -> Result { 27 | use futures::stream::TryStreamExt; // for `try_next` 28 | let mut sum = 0; 29 | while let Some(item) = stream.try_next().await? { 30 | sum += item; 31 | } 32 | Ok(sum) 33 | } 34 | // ANCHOR_END: nexts 35 | 36 | #[test] 37 | fn run_sum_with_next() { 38 | let mut stream = stream::iter(vec![2, 3]); 39 | let pin: Pin<&mut stream::Iter<_>> = Pin::new(&mut stream); 40 | assert_eq!(5, block_on(sum_with_next(pin))); 41 | } 42 | 43 | #[test] 44 | fn run_sum_with_try_next() { 45 | let mut stream = stream::iter(vec![Ok(2), Ok(3)]); 46 | let pin: Pin<&mut stream::Iter<_>> = Pin::new(&mut stream); 47 | assert_eq!(5, block_on(sum_with_try_next(pin)).unwrap()); 48 | } 49 | 50 | #[allow(unused)] 51 | // ANCHOR: try_for_each_concurrent 52 | async fn jump_around( 53 | mut stream: Pin<&mut dyn Stream>>, 54 | ) -> Result<(), io::Error> { 55 | use futures::stream::TryStreamExt; // for `try_for_each_concurrent` 56 | const MAX_CONCURRENT_JUMPERS: usize = 100; 57 | 58 | stream.try_for_each_concurrent(MAX_CONCURRENT_JUMPERS, |num| async move { 59 | jump_n_times(num).await?; 60 | report_n_jumps(num).await?; 61 | Ok(()) 62 | }).await?; 63 | 64 | Ok(()) 65 | } 66 | // ANCHOR_END: try_for_each_concurrent 67 | 68 | async fn jump_n_times(_: u8) -> Result<(), io::Error> { Ok(()) } 69 | async fn report_n_jumps(_: u8) -> Result<(), io::Error> { Ok(()) } 70 | -------------------------------------------------------------------------------- /examples/06_02_join/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "06_02_join" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/06_02_join/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | 3 | struct Book; 4 | struct Music; 5 | async fn get_book() -> Book { Book } 6 | async fn get_music() -> Music { Music } 7 | 8 | mod naiive { 9 | use super::*; 10 | // ANCHOR: naiive 11 | async fn get_book_and_music() -> (Book, Music) { 12 | let book = get_book().await; 13 | let music = get_music().await; 14 | (book, music) 15 | } 16 | // ANCHOR_END: naiive 17 | } 18 | 19 | mod other_langs { 20 | use super::*; 21 | // ANCHOR: other_langs 22 | // WRONG -- don't do this 23 | async fn get_book_and_music() -> (Book, Music) { 24 | let book_future = get_book(); 25 | let music_future = get_music(); 26 | (book_future.await, music_future.await) 27 | } 28 | // ANCHOR_END: other_langs 29 | } 30 | 31 | mod join { 32 | use super::*; 33 | // ANCHOR: join 34 | use futures::join; 35 | 36 | async fn get_book_and_music() -> (Book, Music) { 37 | let book_fut = get_book(); 38 | let music_fut = get_music(); 39 | join!(book_fut, music_fut) 40 | } 41 | // ANCHOR_END: join 42 | } 43 | 44 | mod try_join { 45 | use super::{Book, Music}; 46 | // ANCHOR: try_join 47 | use futures::try_join; 48 | 49 | async fn get_book() -> Result { /* ... */ Ok(Book) } 50 | async fn get_music() -> Result { /* ... */ Ok(Music) } 51 | 52 | async fn get_book_and_music() -> Result<(Book, Music), String> { 53 | let book_fut = get_book(); 54 | let music_fut = get_music(); 55 | try_join!(book_fut, music_fut) 56 | } 57 | // ANCHOR_END: try_join 58 | } 59 | 60 | mod mismatched_err { 61 | use super::{Book, Music}; 62 | // ANCHOR: try_join_map_err 63 | use futures::{ 64 | future::TryFutureExt, 65 | try_join, 66 | }; 67 | 68 | async fn get_book() -> Result { /* ... */ Ok(Book) } 69 | async fn get_music() -> Result { /* ... */ Ok(Music) } 70 | 71 | async fn get_book_and_music() -> Result<(Book, Music), String> { 72 | let book_fut = get_book().map_err(|()| "Unable to get book".to_string()); 73 | let music_fut = get_music(); 74 | try_join!(book_fut, music_fut) 75 | } 76 | // ANCHOR_END: try_join_map_err 77 | } 78 | -------------------------------------------------------------------------------- /examples/06_03_select/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "06_03_select" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/06_03_select/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | #![recursion_limit="128"] 3 | 4 | mod example { 5 | // ANCHOR: example 6 | use futures::{ 7 | future::FutureExt, // for `.fuse()` 8 | pin_mut, 9 | select, 10 | }; 11 | 12 | async fn task_one() { /* ... */ } 13 | async fn task_two() { /* ... */ } 14 | 15 | async fn race_tasks() { 16 | let t1 = task_one().fuse(); 17 | let t2 = task_two().fuse(); 18 | 19 | pin_mut!(t1, t2); 20 | 21 | select! { 22 | () = t1 => println!("task one completed first"), 23 | () = t2 => println!("task two completed first"), 24 | } 25 | } 26 | // ANCHOR_END: example 27 | } 28 | 29 | mod default_and_complete { 30 | // ANCHOR: default_and_complete 31 | use futures::{future, select}; 32 | 33 | async fn count() { 34 | let mut a_fut = future::ready(4); 35 | let mut b_fut = future::ready(6); 36 | let mut total = 0; 37 | 38 | loop { 39 | select! { 40 | a = a_fut => total += a, 41 | b = b_fut => total += b, 42 | complete => break, 43 | default => unreachable!(), // never runs (futures are ready, then complete) 44 | }; 45 | } 46 | assert_eq!(total, 10); 47 | } 48 | // ANCHOR_END: default_and_complete 49 | 50 | #[test] 51 | fn run_count() { 52 | futures::executor::block_on(count()); 53 | } 54 | } 55 | 56 | mod fused_stream { 57 | // ANCHOR: fused_stream 58 | use futures::{ 59 | stream::{Stream, StreamExt, FusedStream}, 60 | select, 61 | }; 62 | 63 | async fn add_two_streams( 64 | mut s1: impl Stream + FusedStream + Unpin, 65 | mut s2: impl Stream + FusedStream + Unpin, 66 | ) -> u8 { 67 | let mut total = 0; 68 | 69 | loop { 70 | let item = select! { 71 | x = s1.next() => x, 72 | x = s2.next() => x, 73 | complete => break, 74 | }; 75 | if let Some(next_num) = item { 76 | total += next_num; 77 | } 78 | } 79 | 80 | total 81 | } 82 | // ANCHOR_END: fused_stream 83 | } 84 | 85 | mod fuse_terminated { 86 | // ANCHOR: fuse_terminated 87 | use futures::{ 88 | future::{Fuse, FusedFuture, FutureExt}, 89 | stream::{FusedStream, Stream, StreamExt}, 90 | pin_mut, 91 | select, 92 | }; 93 | 94 | async fn get_new_num() -> u8 { /* ... */ 5 } 95 | 96 | async fn run_on_new_num(_: u8) { /* ... */ } 97 | 98 | async fn run_loop( 99 | mut interval_timer: impl Stream + FusedStream + Unpin, 100 | starting_num: u8, 101 | ) { 102 | let run_on_new_num_fut = run_on_new_num(starting_num).fuse(); 103 | let get_new_num_fut = Fuse::terminated(); 104 | pin_mut!(run_on_new_num_fut, get_new_num_fut); 105 | loop { 106 | select! { 107 | () = interval_timer.select_next_some() => { 108 | // The timer has elapsed. Start a new `get_new_num_fut` 109 | // if one was not already running. 110 | if get_new_num_fut.is_terminated() { 111 | get_new_num_fut.set(get_new_num().fuse()); 112 | } 113 | }, 114 | new_num = get_new_num_fut => { 115 | // A new number has arrived-- start a new `run_on_new_num_fut`, 116 | // dropping the old one. 117 | run_on_new_num_fut.set(run_on_new_num(new_num).fuse()); 118 | }, 119 | // Run the `run_on_new_num_fut` 120 | () = run_on_new_num_fut => {}, 121 | // panic if everything completed, since the `interval_timer` should 122 | // keep yielding values indefinitely. 123 | complete => panic!("`interval_timer` completed unexpectedly"), 124 | } 125 | } 126 | } 127 | // ANCHOR_END: fuse_terminated 128 | } 129 | 130 | mod futures_unordered { 131 | // ANCHOR: futures_unordered 132 | use futures::{ 133 | future::{Fuse, FusedFuture, FutureExt}, 134 | stream::{FusedStream, FuturesUnordered, Stream, StreamExt}, 135 | pin_mut, 136 | select, 137 | }; 138 | 139 | async fn get_new_num() -> u8 { /* ... */ 5 } 140 | 141 | async fn run_on_new_num(_: u8) -> u8 { /* ... */ 5 } 142 | 143 | // Runs `run_on_new_num` with the latest number 144 | // retrieved from `get_new_num`. 145 | // 146 | // `get_new_num` is re-run every time a timer elapses, 147 | // immediately cancelling the currently running 148 | // `run_on_new_num` and replacing it with the newly 149 | // returned value. 150 | async fn run_loop( 151 | mut interval_timer: impl Stream + FusedStream + Unpin, 152 | starting_num: u8, 153 | ) { 154 | let mut run_on_new_num_futs = FuturesUnordered::new(); 155 | run_on_new_num_futs.push(run_on_new_num(starting_num)); 156 | let get_new_num_fut = Fuse::terminated(); 157 | pin_mut!(get_new_num_fut); 158 | loop { 159 | select! { 160 | () = interval_timer.select_next_some() => { 161 | // The timer has elapsed. Start a new `get_new_num_fut` 162 | // if one was not already running. 163 | if get_new_num_fut.is_terminated() { 164 | get_new_num_fut.set(get_new_num().fuse()); 165 | } 166 | }, 167 | new_num = get_new_num_fut => { 168 | // A new number has arrived-- start a new `run_on_new_num_fut`. 169 | run_on_new_num_futs.push(run_on_new_num(new_num)); 170 | }, 171 | // Run the `run_on_new_num_futs` and check if any have completed 172 | res = run_on_new_num_futs.select_next_some() => { 173 | println!("run_on_new_num_fut returned {:?}", res); 174 | }, 175 | // panic if everything completed, since the `interval_timer` should 176 | // keep yielding values indefinitely. 177 | complete => panic!("`interval_timer` completed unexpectedly"), 178 | } 179 | } 180 | } 181 | 182 | // ANCHOR_END: futures_unordered 183 | } 184 | -------------------------------------------------------------------------------- /examples/07_05_recursion/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "07_05_recursion" 3 | version = "0.1.0" 4 | authors = ["Taylor Cramer "] 5 | edition = "2018" 6 | 7 | [lib] 8 | 9 | [dev-dependencies] 10 | futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nightly"] } 11 | -------------------------------------------------------------------------------- /examples/07_05_recursion/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | #![feature(async_await)] 3 | #![allow(dead_code)] 4 | 5 | // ANCHOR: example 6 | use futures::future::{BoxFuture, FutureExt}; 7 | 8 | fn recursive() -> BoxFuture<'static, ()> { 9 | async move { 10 | recursive().await; 11 | recursive().await; 12 | }.boxed() 13 | } 14 | // ANCHOR_END: example 15 | -------------------------------------------------------------------------------- /examples/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "01_02_why_async" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 8 | ] 9 | 10 | [[package]] 11 | name = "01_04_async_await_primer" 12 | version = "0.1.0" 13 | dependencies = [ 14 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 15 | ] 16 | 17 | [[package]] 18 | name = "01_05_http_server" 19 | version = "0.1.0" 20 | dependencies = [ 21 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 22 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 23 | "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", 24 | "reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", 25 | ] 26 | 27 | [[package]] 28 | name = "02_02_future_trait" 29 | version = "0.1.0" 30 | 31 | [[package]] 32 | name = "02_03_timer" 33 | version = "0.1.0" 34 | dependencies = [ 35 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 36 | ] 37 | 38 | [[package]] 39 | name = "02_04_executor" 40 | version = "0.1.0" 41 | dependencies = [ 42 | "02_03_timer 0.1.0", 43 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 44 | ] 45 | 46 | [[package]] 47 | name = "03_01_async_await" 48 | version = "0.1.0" 49 | dependencies = [ 50 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 51 | ] 52 | 53 | [[package]] 54 | name = "05_01_streams" 55 | version = "0.1.0" 56 | dependencies = [ 57 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 58 | ] 59 | 60 | [[package]] 61 | name = "05_02_iteration_and_concurrency" 62 | version = "0.1.0" 63 | dependencies = [ 64 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 65 | ] 66 | 67 | [[package]] 68 | name = "06_02_join" 69 | version = "0.1.0" 70 | dependencies = [ 71 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 72 | ] 73 | 74 | [[package]] 75 | name = "06_03_select" 76 | version = "0.1.0" 77 | dependencies = [ 78 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 79 | ] 80 | 81 | [[package]] 82 | name = "07_05_recursion" 83 | version = "0.1.0" 84 | dependencies = [ 85 | "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 86 | ] 87 | 88 | [[package]] 89 | name = "adler32" 90 | version = "1.0.4" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | 93 | [[package]] 94 | name = "aho-corasick" 95 | version = "0.7.6" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | dependencies = [ 98 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 99 | ] 100 | 101 | [[package]] 102 | name = "arrayvec" 103 | version = "0.4.11" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | dependencies = [ 106 | "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 107 | ] 108 | 109 | [[package]] 110 | name = "autocfg" 111 | version = "0.1.6" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | 114 | [[package]] 115 | name = "backtrace" 116 | version = "0.3.37" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | dependencies = [ 119 | "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 120 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 121 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 122 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 123 | ] 124 | 125 | [[package]] 126 | name = "backtrace-sys" 127 | version = "0.1.31" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | dependencies = [ 130 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 131 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 132 | ] 133 | 134 | [[package]] 135 | name = "base64" 136 | version = "0.10.1" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | dependencies = [ 139 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 140 | ] 141 | 142 | [[package]] 143 | name = "bitflags" 144 | version = "1.1.0" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | 147 | [[package]] 148 | name = "byteorder" 149 | version = "1.3.2" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | 152 | [[package]] 153 | name = "bytes" 154 | version = "0.4.12" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | dependencies = [ 157 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 160 | ] 161 | 162 | [[package]] 163 | name = "c2-chacha" 164 | version = "0.2.2" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | dependencies = [ 167 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 168 | "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 169 | ] 170 | 171 | [[package]] 172 | name = "cc" 173 | version = "1.0.45" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | 176 | [[package]] 177 | name = "cfg-if" 178 | version = "0.1.9" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | 181 | [[package]] 182 | name = "cloudabi" 183 | version = "0.0.3" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | dependencies = [ 186 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 187 | ] 188 | 189 | [[package]] 190 | name = "cookie" 191 | version = "0.12.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | dependencies = [ 194 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 195 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 196 | ] 197 | 198 | [[package]] 199 | name = "cookie_store" 200 | version = "0.7.0" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | dependencies = [ 203 | "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 204 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 205 | "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 206 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 207 | "publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 208 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 209 | "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", 210 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 211 | "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 212 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 213 | ] 214 | 215 | [[package]] 216 | name = "core-foundation" 217 | version = "0.6.4" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | dependencies = [ 220 | "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 221 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 222 | ] 223 | 224 | [[package]] 225 | name = "core-foundation-sys" 226 | version = "0.6.2" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | 229 | [[package]] 230 | name = "crc32fast" 231 | version = "1.2.0" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | dependencies = [ 234 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 235 | ] 236 | 237 | [[package]] 238 | name = "crossbeam-deque" 239 | version = "0.7.1" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | dependencies = [ 242 | "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 243 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 244 | ] 245 | 246 | [[package]] 247 | name = "crossbeam-epoch" 248 | version = "0.7.2" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | dependencies = [ 251 | "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 252 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 253 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 254 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 255 | "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 256 | "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 257 | ] 258 | 259 | [[package]] 260 | name = "crossbeam-queue" 261 | version = "0.1.2" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | dependencies = [ 264 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 265 | ] 266 | 267 | [[package]] 268 | name = "crossbeam-utils" 269 | version = "0.6.6" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | dependencies = [ 272 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 273 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 274 | ] 275 | 276 | [[package]] 277 | name = "dtoa" 278 | version = "0.4.4" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | 281 | [[package]] 282 | name = "either" 283 | version = "1.5.3" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | 286 | [[package]] 287 | name = "encoding_rs" 288 | version = "0.8.20" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | dependencies = [ 291 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 292 | ] 293 | 294 | [[package]] 295 | name = "error-chain" 296 | version = "0.12.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | dependencies = [ 299 | "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", 300 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 301 | ] 302 | 303 | [[package]] 304 | name = "failure" 305 | version = "0.1.5" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | dependencies = [ 308 | "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", 309 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 310 | ] 311 | 312 | [[package]] 313 | name = "failure_derive" 314 | version = "0.1.5" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | dependencies = [ 317 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 318 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 319 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 320 | "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 321 | ] 322 | 323 | [[package]] 324 | name = "flate2" 325 | version = "1.0.11" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | dependencies = [ 328 | "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 329 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 331 | ] 332 | 333 | [[package]] 334 | name = "fnv" 335 | version = "1.0.6" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | 338 | [[package]] 339 | name = "foreign-types" 340 | version = "0.3.2" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | dependencies = [ 343 | "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 344 | ] 345 | 346 | [[package]] 347 | name = "foreign-types-shared" 348 | version = "0.1.1" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | 351 | [[package]] 352 | name = "fuchsia-cprng" 353 | version = "0.1.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | 356 | [[package]] 357 | name = "fuchsia-zircon" 358 | version = "0.3.3" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | dependencies = [ 361 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 362 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 363 | ] 364 | 365 | [[package]] 366 | name = "fuchsia-zircon-sys" 367 | version = "0.3.3" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | 370 | [[package]] 371 | name = "futures" 372 | version = "0.1.29" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | 375 | [[package]] 376 | name = "futures-channel-preview" 377 | version = "0.3.0-alpha.17" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | dependencies = [ 380 | "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 382 | ] 383 | 384 | [[package]] 385 | name = "futures-core-preview" 386 | version = "0.3.0-alpha.17" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | 389 | [[package]] 390 | name = "futures-cpupool" 391 | version = "0.1.8" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | dependencies = [ 394 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 395 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 396 | ] 397 | 398 | [[package]] 399 | name = "futures-executor-preview" 400 | version = "0.3.0-alpha.17" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | dependencies = [ 403 | "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 404 | "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 405 | "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 406 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 407 | ] 408 | 409 | [[package]] 410 | name = "futures-io-preview" 411 | version = "0.3.0-alpha.17" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | 414 | [[package]] 415 | name = "futures-preview" 416 | version = "0.3.0-alpha.17" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | dependencies = [ 419 | "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 420 | "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 421 | "futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 422 | "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 423 | "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 424 | "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 425 | ] 426 | 427 | [[package]] 428 | name = "futures-select-macro-preview" 429 | version = "0.3.0-alpha.17" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | dependencies = [ 432 | "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", 433 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 434 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 435 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 436 | ] 437 | 438 | [[package]] 439 | name = "futures-sink-preview" 440 | version = "0.3.0-alpha.17" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | dependencies = [ 443 | "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 444 | ] 445 | 446 | [[package]] 447 | name = "futures-util-preview" 448 | version = "0.3.0-alpha.17" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | dependencies = [ 451 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 452 | "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 453 | "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 454 | "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 455 | "futures-select-macro-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 456 | "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", 457 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 458 | "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", 459 | "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", 460 | "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 461 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 462 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 463 | ] 464 | 465 | [[package]] 466 | name = "getrandom" 467 | version = "0.1.12" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | dependencies = [ 470 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 471 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 472 | "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 473 | ] 474 | 475 | [[package]] 476 | name = "h2" 477 | version = "0.1.26" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | dependencies = [ 480 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 481 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 482 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 483 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 484 | "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 485 | "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 486 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 487 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 488 | "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 489 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 490 | ] 491 | 492 | [[package]] 493 | name = "http" 494 | version = "0.1.18" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | dependencies = [ 497 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 498 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 499 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 500 | ] 501 | 502 | [[package]] 503 | name = "http-body" 504 | version = "0.1.0" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | dependencies = [ 507 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 508 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 509 | "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 510 | "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 511 | ] 512 | 513 | [[package]] 514 | name = "httparse" 515 | version = "1.3.4" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | 518 | [[package]] 519 | name = "hyper" 520 | version = "0.12.35" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | dependencies = [ 523 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 524 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 525 | "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 526 | "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", 527 | "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 528 | "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 530 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 531 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 532 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 533 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 534 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 535 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 536 | "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", 537 | "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 538 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 539 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 540 | "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 541 | "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 542 | "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 543 | "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 544 | "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 545 | ] 546 | 547 | [[package]] 548 | name = "hyper-tls" 549 | version = "0.3.2" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | dependencies = [ 552 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 553 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 554 | "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", 555 | "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 556 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 557 | ] 558 | 559 | [[package]] 560 | name = "idna" 561 | version = "0.1.5" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | dependencies = [ 564 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 565 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 566 | "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 567 | ] 568 | 569 | [[package]] 570 | name = "idna" 571 | version = "0.2.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | dependencies = [ 574 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 575 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 576 | "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 577 | ] 578 | 579 | [[package]] 580 | name = "indexmap" 581 | version = "1.2.0" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | 584 | [[package]] 585 | name = "iovec" 586 | version = "0.1.2" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | dependencies = [ 589 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 590 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 591 | ] 592 | 593 | [[package]] 594 | name = "itoa" 595 | version = "0.4.4" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | 598 | [[package]] 599 | name = "kernel32-sys" 600 | version = "0.2.2" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | dependencies = [ 603 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 604 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 605 | ] 606 | 607 | [[package]] 608 | name = "lazy_static" 609 | version = "1.4.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | 612 | [[package]] 613 | name = "libc" 614 | version = "0.2.62" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | 617 | [[package]] 618 | name = "lock_api" 619 | version = "0.1.5" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | dependencies = [ 622 | "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 623 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 624 | ] 625 | 626 | [[package]] 627 | name = "log" 628 | version = "0.4.8" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | dependencies = [ 631 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 632 | ] 633 | 634 | [[package]] 635 | name = "matches" 636 | version = "0.1.8" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | 639 | [[package]] 640 | name = "memchr" 641 | version = "2.2.1" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | 644 | [[package]] 645 | name = "memoffset" 646 | version = "0.5.1" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | dependencies = [ 649 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 650 | ] 651 | 652 | [[package]] 653 | name = "mime" 654 | version = "0.3.14" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | 657 | [[package]] 658 | name = "mime_guess" 659 | version = "2.0.1" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | dependencies = [ 662 | "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 663 | "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 664 | ] 665 | 666 | [[package]] 667 | name = "miniz_oxide" 668 | version = "0.3.2" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | dependencies = [ 671 | "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 672 | ] 673 | 674 | [[package]] 675 | name = "mio" 676 | version = "0.6.19" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | dependencies = [ 679 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 680 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 681 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 682 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 683 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 684 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 685 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 686 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 687 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 688 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 689 | ] 690 | 691 | [[package]] 692 | name = "miow" 693 | version = "0.2.1" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | dependencies = [ 696 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 697 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 698 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 699 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 700 | ] 701 | 702 | [[package]] 703 | name = "native-tls" 704 | version = "0.2.3" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | dependencies = [ 707 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 708 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 709 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 710 | "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)", 711 | "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 712 | "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", 713 | "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 714 | "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 715 | "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 716 | "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 717 | ] 718 | 719 | [[package]] 720 | name = "net2" 721 | version = "0.2.33" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | dependencies = [ 724 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 725 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 726 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 727 | ] 728 | 729 | [[package]] 730 | name = "nodrop" 731 | version = "0.1.13" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | 734 | [[package]] 735 | name = "num_cpus" 736 | version = "1.10.1" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | dependencies = [ 739 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 740 | ] 741 | 742 | [[package]] 743 | name = "openssl" 744 | version = "0.10.24" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | dependencies = [ 747 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 748 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 749 | "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 750 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 751 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 752 | "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", 753 | ] 754 | 755 | [[package]] 756 | name = "openssl-probe" 757 | version = "0.1.2" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | 760 | [[package]] 761 | name = "openssl-sys" 762 | version = "0.9.49" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | dependencies = [ 765 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 766 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 767 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 768 | "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 769 | "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 770 | ] 771 | 772 | [[package]] 773 | name = "owning_ref" 774 | version = "0.4.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | dependencies = [ 777 | "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 778 | ] 779 | 780 | [[package]] 781 | name = "parking_lot" 782 | version = "0.7.1" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | dependencies = [ 785 | "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 786 | "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 787 | ] 788 | 789 | [[package]] 790 | name = "parking_lot_core" 791 | version = "0.4.0" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | dependencies = [ 794 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 795 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 796 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 797 | "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 798 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 799 | ] 800 | 801 | [[package]] 802 | name = "percent-encoding" 803 | version = "1.0.1" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | 806 | [[package]] 807 | name = "percent-encoding" 808 | version = "2.1.0" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | 811 | [[package]] 812 | name = "pin-utils" 813 | version = "0.1.0-alpha.4" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | 816 | [[package]] 817 | name = "pkg-config" 818 | version = "0.3.16" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | 821 | [[package]] 822 | name = "ppv-lite86" 823 | version = "0.2.5" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | 826 | [[package]] 827 | name = "proc-macro-hack" 828 | version = "0.5.9" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | dependencies = [ 831 | "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 832 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 833 | "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 834 | ] 835 | 836 | [[package]] 837 | name = "proc-macro-nested" 838 | version = "0.1.3" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | 841 | [[package]] 842 | name = "proc-macro2" 843 | version = "0.4.30" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | dependencies = [ 846 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "proc-macro2" 851 | version = "1.0.4" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | dependencies = [ 854 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 855 | ] 856 | 857 | [[package]] 858 | name = "publicsuffix" 859 | version = "1.5.3" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | dependencies = [ 862 | "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 863 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 864 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 865 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 866 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 867 | ] 868 | 869 | [[package]] 870 | name = "quote" 871 | version = "0.6.13" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | dependencies = [ 874 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 875 | ] 876 | 877 | [[package]] 878 | name = "quote" 879 | version = "1.0.2" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | dependencies = [ 882 | "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 883 | ] 884 | 885 | [[package]] 886 | name = "rand" 887 | version = "0.6.5" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | dependencies = [ 890 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 891 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 892 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 893 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 894 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 895 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 896 | "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 897 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 898 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 899 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 900 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 901 | ] 902 | 903 | [[package]] 904 | name = "rand" 905 | version = "0.7.2" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | dependencies = [ 908 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 909 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 910 | "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 911 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 912 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 913 | ] 914 | 915 | [[package]] 916 | name = "rand_chacha" 917 | version = "0.1.1" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | dependencies = [ 920 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 921 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 922 | ] 923 | 924 | [[package]] 925 | name = "rand_chacha" 926 | version = "0.2.1" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | dependencies = [ 929 | "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 930 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 931 | ] 932 | 933 | [[package]] 934 | name = "rand_core" 935 | version = "0.3.1" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | dependencies = [ 938 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 939 | ] 940 | 941 | [[package]] 942 | name = "rand_core" 943 | version = "0.4.2" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | 946 | [[package]] 947 | name = "rand_core" 948 | version = "0.5.1" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | dependencies = [ 951 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 952 | ] 953 | 954 | [[package]] 955 | name = "rand_hc" 956 | version = "0.1.0" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | dependencies = [ 959 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 960 | ] 961 | 962 | [[package]] 963 | name = "rand_hc" 964 | version = "0.2.0" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | dependencies = [ 967 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 968 | ] 969 | 970 | [[package]] 971 | name = "rand_isaac" 972 | version = "0.1.1" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | dependencies = [ 975 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 976 | ] 977 | 978 | [[package]] 979 | name = "rand_jitter" 980 | version = "0.1.4" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | dependencies = [ 983 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 984 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 985 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 986 | ] 987 | 988 | [[package]] 989 | name = "rand_os" 990 | version = "0.1.3" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | dependencies = [ 993 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 994 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 995 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 996 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 997 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 998 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "rand_pcg" 1003 | version = "0.1.2" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | dependencies = [ 1006 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1007 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "rand_xorshift" 1012 | version = "0.1.1" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | dependencies = [ 1015 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "rdrand" 1020 | version = "0.4.0" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | dependencies = [ 1023 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "redox_syscall" 1028 | version = "0.1.56" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | 1031 | [[package]] 1032 | name = "regex" 1033 | version = "1.3.1" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | dependencies = [ 1036 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", 1037 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1038 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1039 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "regex-syntax" 1044 | version = "0.6.12" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | 1047 | [[package]] 1048 | name = "remove_dir_all" 1049 | version = "0.5.2" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | dependencies = [ 1052 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "reqwest" 1057 | version = "0.9.20" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | dependencies = [ 1060 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1061 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1062 | "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 1063 | "cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1064 | "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", 1065 | "flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1066 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1067 | "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 1068 | "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", 1069 | "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1070 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1071 | "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 1072 | "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1073 | "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1074 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1075 | "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", 1076 | "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 1077 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 1078 | "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", 1079 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1080 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1081 | "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1082 | "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1083 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1084 | "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", 1085 | "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "rustc-demangle" 1090 | version = "0.1.16" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | 1093 | [[package]] 1094 | name = "rustc_version" 1095 | version = "0.2.3" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | dependencies = [ 1098 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1099 | ] 1100 | 1101 | [[package]] 1102 | name = "ryu" 1103 | version = "1.0.0" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | 1106 | [[package]] 1107 | name = "schannel" 1108 | version = "0.1.16" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | dependencies = [ 1111 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1112 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1113 | ] 1114 | 1115 | [[package]] 1116 | name = "scopeguard" 1117 | version = "0.3.3" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | 1120 | [[package]] 1121 | name = "scopeguard" 1122 | version = "1.0.0" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | 1125 | [[package]] 1126 | name = "security-framework" 1127 | version = "0.3.1" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | dependencies = [ 1130 | "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 1131 | "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1132 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 1133 | "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "security-framework-sys" 1138 | version = "0.3.1" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | dependencies = [ 1141 | "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "semver" 1146 | version = "0.9.0" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | dependencies = [ 1149 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1150 | ] 1151 | 1152 | [[package]] 1153 | name = "semver-parser" 1154 | version = "0.7.0" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | 1157 | [[package]] 1158 | name = "serde" 1159 | version = "1.0.101" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | dependencies = [ 1162 | "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1163 | ] 1164 | 1165 | [[package]] 1166 | name = "serde_derive" 1167 | version = "1.0.101" 1168 | source = "registry+https://github.com/rust-lang/crates.io-index" 1169 | dependencies = [ 1170 | "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1171 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1172 | "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "serde_json" 1177 | version = "1.0.40" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | dependencies = [ 1180 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1181 | "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1182 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "serde_urlencoded" 1187 | version = "0.5.5" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | dependencies = [ 1190 | "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1191 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1192 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1193 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "slab" 1198 | version = "0.4.2" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | 1201 | [[package]] 1202 | name = "smallvec" 1203 | version = "0.6.10" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | 1206 | [[package]] 1207 | name = "stable_deref_trait" 1208 | version = "1.1.1" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | 1211 | [[package]] 1212 | name = "string" 1213 | version = "0.2.1" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | dependencies = [ 1216 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1217 | ] 1218 | 1219 | [[package]] 1220 | name = "syn" 1221 | version = "0.15.44" 1222 | source = "registry+https://github.com/rust-lang/crates.io-index" 1223 | dependencies = [ 1224 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1225 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1226 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1227 | ] 1228 | 1229 | [[package]] 1230 | name = "syn" 1231 | version = "1.0.5" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | dependencies = [ 1234 | "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1235 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1236 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "synstructure" 1241 | version = "0.10.2" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | dependencies = [ 1244 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1245 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1246 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 1247 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "tempfile" 1252 | version = "3.1.0" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | dependencies = [ 1255 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1256 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 1257 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1258 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1259 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1260 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "thread_local" 1265 | version = "0.3.6" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | dependencies = [ 1268 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1269 | ] 1270 | 1271 | [[package]] 1272 | name = "time" 1273 | version = "0.1.42" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | dependencies = [ 1276 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 1277 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1278 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "tokio" 1283 | version = "0.1.22" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | dependencies = [ 1286 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1287 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1288 | "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", 1289 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1290 | "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1291 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1292 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1293 | "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1294 | "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1295 | "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1296 | "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1297 | ] 1298 | 1299 | [[package]] 1300 | name = "tokio-buf" 1301 | version = "0.1.1" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | dependencies = [ 1304 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1305 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1306 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1307 | ] 1308 | 1309 | [[package]] 1310 | name = "tokio-current-thread" 1311 | version = "0.1.6" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | dependencies = [ 1314 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1315 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "tokio-executor" 1320 | version = "0.1.8" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | dependencies = [ 1323 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1324 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "tokio-io" 1329 | version = "0.1.12" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | dependencies = [ 1332 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1333 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1334 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1335 | ] 1336 | 1337 | [[package]] 1338 | name = "tokio-reactor" 1339 | version = "0.1.9" 1340 | source = "registry+https://github.com/rust-lang/crates.io-index" 1341 | dependencies = [ 1342 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1343 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1344 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1345 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1346 | "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", 1347 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1348 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1349 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1350 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1351 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1352 | "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "tokio-sync" 1357 | version = "0.1.6" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | dependencies = [ 1360 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1361 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "tokio-tcp" 1366 | version = "0.1.3" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | dependencies = [ 1369 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1370 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1371 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1372 | "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", 1373 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1374 | "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1375 | ] 1376 | 1377 | [[package]] 1378 | name = "tokio-threadpool" 1379 | version = "0.1.15" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | dependencies = [ 1382 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1383 | "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1384 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1385 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1386 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1387 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1388 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1389 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1390 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "tokio-timer" 1395 | version = "0.2.11" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | dependencies = [ 1398 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1399 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1400 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1401 | "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "try-lock" 1406 | version = "0.2.2" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | 1409 | [[package]] 1410 | name = "try_from" 1411 | version = "0.3.2" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | dependencies = [ 1414 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "unicase" 1419 | version = "2.5.1" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | dependencies = [ 1422 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1423 | ] 1424 | 1425 | [[package]] 1426 | name = "unicode-bidi" 1427 | version = "0.3.4" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | dependencies = [ 1430 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "unicode-normalization" 1435 | version = "0.1.8" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | dependencies = [ 1438 | "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "unicode-xid" 1443 | version = "0.1.0" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | 1446 | [[package]] 1447 | name = "unicode-xid" 1448 | version = "0.2.0" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | 1451 | [[package]] 1452 | name = "url" 1453 | version = "1.7.2" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | dependencies = [ 1456 | "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1457 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1458 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1459 | ] 1460 | 1461 | [[package]] 1462 | name = "url" 1463 | version = "2.1.0" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | dependencies = [ 1466 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1467 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1468 | "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "uuid" 1473 | version = "0.7.4" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | dependencies = [ 1476 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1477 | ] 1478 | 1479 | [[package]] 1480 | name = "vcpkg" 1481 | version = "0.2.7" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | 1484 | [[package]] 1485 | name = "version_check" 1486 | version = "0.1.5" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | 1489 | [[package]] 1490 | name = "want" 1491 | version = "0.2.0" 1492 | source = "registry+https://github.com/rust-lang/crates.io-index" 1493 | dependencies = [ 1494 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1495 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1496 | "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "wasi" 1501 | version = "0.7.0" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | 1504 | [[package]] 1505 | name = "winapi" 1506 | version = "0.2.8" 1507 | source = "registry+https://github.com/rust-lang/crates.io-index" 1508 | 1509 | [[package]] 1510 | name = "winapi" 1511 | version = "0.3.8" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | dependencies = [ 1514 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1515 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1516 | ] 1517 | 1518 | [[package]] 1519 | name = "winapi-build" 1520 | version = "0.1.1" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | 1523 | [[package]] 1524 | name = "winapi-i686-pc-windows-gnu" 1525 | version = "0.4.0" 1526 | source = "registry+https://github.com/rust-lang/crates.io-index" 1527 | 1528 | [[package]] 1529 | name = "winapi-x86_64-pc-windows-gnu" 1530 | version = "0.4.0" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | 1533 | [[package]] 1534 | name = "winreg" 1535 | version = "0.6.2" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | dependencies = [ 1538 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1539 | ] 1540 | 1541 | [[package]] 1542 | name = "ws2_32-sys" 1543 | version = "0.2.1" 1544 | source = "registry+https://github.com/rust-lang/crates.io-index" 1545 | dependencies = [ 1546 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1547 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1548 | ] 1549 | 1550 | [metadata] 1551 | "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 1552 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 1553 | "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" 1554 | "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" 1555 | "checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2" 1556 | "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" 1557 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1558 | "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" 1559 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" 1560 | "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 1561 | "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" 1562 | "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" 1563 | "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" 1564 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1565 | "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" 1566 | "checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" 1567 | "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" 1568 | "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" 1569 | "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 1570 | "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" 1571 | "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" 1572 | "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" 1573 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" 1574 | "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" 1575 | "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 1576 | "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" 1577 | "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" 1578 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" 1579 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" 1580 | "checksum flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaffba6388640136149e18ed080b77a78611c1e1d6de75aedcdf78df5d4682" 1581 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1582 | "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 1583 | "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 1584 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 1585 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1586 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1587 | "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" 1588 | "checksum futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "21c71ed547606de08e9ae744bb3c6d80f5627527ef31ecf2a7210d0e67bc8fae" 1589 | "checksum futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4b141ccf9b7601ef987f36f1c0d9522f76df3bba1cf2e63bfacccc044c4558f5" 1590 | "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 1591 | "checksum futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "87ba260fe51080ba37f063ad5b0732c4ff1f737ea18dcb67833d282cdc2c6f14" 1592 | "checksum futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "082e402605fcb8b1ae1e5ba7d7fdfd3e31ef510e2a8367dd92927bb41ae41b3a" 1593 | "checksum futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "bf25f91c8a9a1f64c451e91b43ba269ed359b9f52d35ed4b3ce3f9c842435867" 1594 | "checksum futures-select-macro-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "469d86239defe297ebcaf385ac5e999a77147f2f20eaf2a3aee7bff9e58e20a9" 1595 | "checksum futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4309a25a1069a1f3c10647b227b9afe6722b67a030d3f00a9cbdc171fc038de4" 1596 | "checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e" 1597 | "checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" 1598 | "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 1599 | "checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" 1600 | "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 1601 | "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 1602 | "checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" 1603 | "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" 1604 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1605 | "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1606 | "checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" 1607 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" 1608 | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" 1609 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1610 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1611 | "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" 1612 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" 1613 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1614 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1615 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1616 | "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" 1617 | "checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" 1618 | "checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" 1619 | "checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" 1620 | "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" 1621 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1622 | "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" 1623 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 1624 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" 1625 | "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" 1626 | "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" 1627 | "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1628 | "checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884" 1629 | "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" 1630 | "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" 1631 | "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" 1632 | "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1633 | "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1634 | "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" 1635 | "checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" 1636 | "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" 1637 | "checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" 1638 | "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" 1639 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 1640 | "checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc" 1641 | "checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510" 1642 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 1643 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1644 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1645 | "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" 1646 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1647 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" 1648 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1649 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1650 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1651 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1652 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1653 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1654 | "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1655 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1656 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1657 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1658 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1659 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1660 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 1661 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" 1662 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1663 | "checksum reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6d896143a583047512e59ac54a215cb203c29cc941917343edea3be8df9c78" 1664 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1665 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1666 | "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" 1667 | "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" 1668 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1669 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1670 | "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" 1671 | "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" 1672 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1673 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1674 | "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" 1675 | "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" 1676 | "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" 1677 | "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" 1678 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1679 | "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" 1680 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" 1681 | "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" 1682 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 1683 | "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" 1684 | "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" 1685 | "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1686 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1687 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 1688 | "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 1689 | "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 1690 | "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" 1691 | "checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" 1692 | "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" 1693 | "checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" 1694 | "checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" 1695 | "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" 1696 | "checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" 1697 | "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" 1698 | "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" 1699 | "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" 1700 | "checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" 1701 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1702 | "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" 1703 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1704 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1705 | "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 1706 | "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" 1707 | "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" 1708 | "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" 1709 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1710 | "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 1711 | "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 1712 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1713 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1714 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1715 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1716 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1717 | "checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" 1718 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1719 | -------------------------------------------------------------------------------- /examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "01_02_why_async", 4 | "01_04_async_await_primer", 5 | "01_05_http_server", 6 | "02_02_future_trait", 7 | "02_03_timer", 8 | "02_04_executor", 9 | "03_01_async_await", 10 | "05_01_streams", 11 | "05_02_iteration_and_concurrency", 12 | "06_02_join", 13 | "06_03_select", 14 | "07_05_recursion", 15 | ] 16 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2019-08-21 2 | -------------------------------------------------------------------------------- /src/01_getting_started/01_chapter.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ようこそ Rust の非同期プログラミングへ! 非同期の Rust コードを作りたいなら、キミは適切な本を探し当てたね! 4 | 5 | Web サーバーやデータベース、オペレーティングシステムのいずれかを構築している場合でも、このドキュメントは、Rust の非同期プログラミングツールを使用してハードウェア性能を最大限に活用する方法を示します。 6 | 7 | ## What This Book Covers 8 | 9 | この本は、Rust の非同期な言語機能、ライブラリを使用するための、初心者と熟練者に適した、最新の、包括的なガイドを目指しています。 10 | 11 | - 初期の章では、非同期プログラミングの一般的な概要と、それに対して Rust がどのように取り組んでいるか話します。 12 | 13 | - 中間章では、非同期なコードを書く時に使うことのできる、主なユーティリティと制御フローツールについて説明し、パフォーマンスと再利用性を最大限発揮するために、ライブラリとアプリケーションを構築するときのベストプラクティスを紹介します。 14 | 15 | - 最後の章では、広い範囲の非同期エコシステムについて説明し、一般的た課題を達成するための例をいくつか紹介します 16 | -------------------------------------------------------------------------------- /src/01_getting_started/02_why_async.md: -------------------------------------------------------------------------------- 1 | # なぜ非同期なのか? 2 | 3 | Rust を使うと、高速で安全なソフトウェアが書けます。しかし、なぜ非同期コードを書くんでしょう? 4 | 5 | 非同期コードを使用すると、同じ OS のスレッドで複数のタスクを同時に実行できるようになる。 典型的なスレッドを使ったアプリケーションでは、2 つの Web ページを同時にダウンロードしたい時、次のように 2 つのスレッドに作業を分散します。 6 | 7 | ```rust 8 | {{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites}} 9 | ``` 10 | 11 | これは多くのアプリケーションでうまく機能する。スレッドはこれを行うように設計されているからね。複数の異なるタスクを同時に実行するようにね。 12 | 13 | ただ、いくつか制限もあるんだ。スレッドの切り替えや、スレッド間でのデータ共有をするプロセスにはオーバーヘッドが結構あるのです…。 14 | 15 | ただ何もしないで居座っているスレッドでさえ、貴重なシステムリソースを食いつぶします。これらは、非同期コードが排除するために設計されたコストです。私達は Rust の`async`/`.await`記法を使って、先ほどのコードを書き換えることができます。それも、複数スレッドを作成することなく、一度に複数タスクを実行できるようにね。 16 | 17 | ```rust 18 | {{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites_async}} 19 | ``` 20 | 21 | 全体として、非同期アプリケーションはスレッド実装よりもすごく高速で、使うリソースも少ない可能性があります。ただし、コストがかかってしまいます。 22 | スレッドは OS によってネイティブにサポートされているので、特別なプログラミングモデルは不必要です、どんな関数もスレッドを作成でき、通常の関数と同じくらい簡単にスレッドを使用する関数を呼び出すことが出来ます。 23 | 24 | ただし、非同期関数は、言語もしくはライブラリの特別なサポートが必要になります。Rust では、`async fn`が`future`を返す非同期関数を作ってくれます。関数本体を実行するには`future`を最後まで実行する必要があります。 25 | 26 | 従来のスレッド化されたアプリケーションも非常に効果的で、Rust の小さなメモリ追跡と予測によって`async`を使わなくても十分である可能性を忘れないでください。 27 | 28 | 非同期プログラミングモデルによる複雑性の増加は、常にそれだけの価値があるか分からいないものです。単純なスレッドモデルの使用を考慮することも重要です。 29 | -------------------------------------------------------------------------------- /src/01_getting_started/03_state_of_async_rust.md: -------------------------------------------------------------------------------- 1 | # 非同期 Rust の現状 2 | 3 | 非同期 Rust はエコシステム時間とともに大きく進化してきたため、使うツール、投資するライブラリ、読むべきドキュメントを把握するのは大変です。ただ、標準ライブラリの`Future`トレイトと言語機能の`async` / `await`は最近安定化されました。(パチパチ!) なので、エコシステム全体は新しく安定化された API への移行の真っ最中で、その後、エコシステムの激しい動きは大幅に解消されます。 4 | 5 | しかし現時点では、エコシステムはまだ急速に発展していて、非同期 Rust の経験は磨かれていません。ほとんどのライブラリはまだ、`futures`クレートの 0.1 を使っています。そのため開発者が`futures`0.3 と相互運用したければ`compat`クレートの機能を頻繁に使用する必要があります。 6 | また、トレイトメソッド内の`async fn`構文はまだ実装されていなかったり、分かりやすいコンパイルエラーメッセージはまだなかったりします。`async` / `await`言語機能はまだ、新しいからですね。 7 | 8 | とは言っても、Rust はパフォーマンスが高く、非同期プログラミングに対して人間工学に基づいたサポートもあります、なのであなたが冒険、探検を恐れないのであれば、Rust の非同期プログラミングの世界に飛び込みましょう! ダイブ! 9 | -------------------------------------------------------------------------------- /src/01_getting_started/04_async_await_primer.md: -------------------------------------------------------------------------------- 1 | # `async` / `.await` 入門! 2 | 3 | `async/.await`は通常の同期コードの用に見える非同期関数を作成するための Rust のビルドインツールです。 `async`はコードブロックを`Future`トレイトを実装しているステートマシンに変換するものです。 一方、同期メソッドでブロッキング関数を呼び出すとスレッド全体がブロックされてしまいますが、ブロックされた`Future`はスレッドの制御をもたらし、他の`Future`を実行できるようにします。 4 | 5 | 非同期関数を作成するには次の`async fn`構文を使用できます。 6 | 7 | ```rust 8 | async fn do_something() { ... } 9 | ``` 10 | 11 | `async fn`によってこの関数の返り値は`Future`になります。 12 | `Future`は次のようにエグゼキューターで実行する必要があります。 13 | 14 | ```rust 15 | {{#include ../../examples/01_04_async_await_primer/src/lib.rs:hello_world}} 16 | ``` 17 | 18 | `async fn`内では`.await`を使うことで、ほかの`Future`トレイトを実装する別の型の完了を待つことができます。`block_on`とは異なり、`.await`は現在のスレッドをブロックしません、代わりに、`Future`が完了するのを非同期で待機し、`Future`が現在進行できないときは他のタスクを実行できるようにします。 19 | 20 | 例として、3 つの`async fn`を考えてみましょう。`learn_song`, `sing_song`, `dance`です。 21 | 22 | ```rust 23 | async fn learn_song() -> Song { ... } 24 | async fn sing_song(song: Song) { ... } 25 | async fn dance() { ... } 26 | ``` 27 | 28 | 歌、学習、ダンスを行う方法の一つは、それぞれ個別にブロックすることです。 29 | 30 | ```rust 31 | {{#include ../../examples/01_04_async_await_primer/src/lib.rs:block_on_each}} 32 | ``` 33 | 34 | ただ、この方法では最高のパフォーマンスを実現しているわけではありません。一つのことしか実行してないからね! 35 | 36 | 明らかに、歌を歌うには歌を学ぶ必要があります。しかし、歌を学んだあとに歌うのと、同時に踊ることも可能ですよね? 37 | 38 | これを行うには、同時に実行できる 2 つの独立した`async fn`を作ることです。 39 | 40 | ```rust 41 | {{#include ../../examples/01_04_async_await_primer/src/lib.rs:block_on_main}} 42 | ``` 43 | 44 | この例では、歌を歌う前に歌を学習する必要がありますが、歌を学ぶと同時に踊ることもできます。 `learn_and_sing`で`learn_song().await`ではなく`block_on(learn_son())`を使ってしまうと、スレッドはしばらくの間他のことを行うことができなくなり、同時に踊ることを不可能にします。 45 | 46 | 今学習した、`async / await` の例を試してみましょう! 47 | -------------------------------------------------------------------------------- /src/01_getting_started/05_http_server_example.md: -------------------------------------------------------------------------------- 1 | # HTTP サーバーを書いてみよう! 2 | 3 | `async / .await`を使用してエコーサーバーを構築してみましょう! 4 | 5 | 最初に、`rustup update nightly`で Rust の最新かつ最高のコピーを手に入れてください。 6 | それが完了したら、`cargo +nightly new async-await-echo`を実行して新プロジェクトを作成します。 7 | 8 | `Cargo.toml`ファイルにいくつかの依存関係を追加しましょう 9 | 10 | ```toml 11 | {{#include ../../examples/01_05_http_server/Cargo.toml:9:18}} 12 | ``` 13 | 14 | 依存関係を追加したので、コードを書いていきましょう! 15 | 追加するインポートがいくつかあります 16 | 17 | ```rust 18 | {{#include ../../examples/01_05_http_server/src/lib.rs:imports}} 19 | ``` 20 | 21 | 次はリクエストを処理できるようにしていきましょう。 22 | 23 | ```rust 24 | {{#include ../../examples/01_05_http_server/src/lib.rs:boilerplate}} 25 | ``` 26 | 27 | `cargo run`でターミナルに「Listening on http://127.0.0.1:3000」というメッセージが表示されるはずです。 28 | ブラウザでその URL を開くとどうなりますか? 「hello, world」と見慣れた挨拶が表示されれば順調な証拠です。 おめでとうございます! 29 | Rust で最初の非同期 Web サーバーを作成しました。 30 | 31 | また、リクエスト URL、HTTP のバージョン、ヘッダー、その他のメタデータなどの情報を調べることも出来ます。例えば、次のようにリクエストの URL を出力できます。 32 | 33 | ```rust 34 | println!("Got request at {:?}", req.uri()); 35 | ``` 36 | 37 | お気づきかな?すぐにレスポンスを返すため、リクエストを処理する際に非同期処理をまだ行ってないことに。 38 | 静的なメッセージを返すのではなく、Hyper の HTTP クライアントを使用して、ユーザーのリクエストを別の WEB サイトにプロキシしてみましょう。 39 | 40 | URL を解析することから初めます。 41 | 42 | ```rust 43 | {{#include ../../examples/01_05_http_server/src/lib.rs:parse_url}} 44 | ``` 45 | 46 | 次に、新しく`hyper::Client`を作成し、`GET`リクエストを送りユーザーにレスポンスを返します。 47 | 48 | ```rust 49 | {{#include ../../examples/01_05_http_server/src/lib.rs:get_request}} 50 | ``` 51 | 52 | `Client::get`は`hyper::client::FutureResponse`を返します。 53 | これは、`Future>`を実装します。 54 | `.await`するとき、HTTP リクエストが送信され、現在のタスクが一時停止され、レスポンスが利用可能になったらタスクがキューに入れられて続行されます。 55 | 56 | `cargo run`をして、`http://127.0.0.1:3000/foo`を開いてみてください、Rust のホームページと以下の出力がターミナルで見れるはずです。 57 | 58 | ``` 59 | Listening on http://127.0.0.1:3000 60 | Got request at /foo 61 | making request to http://www.rust-lang.org/en-US/ 62 | request finished-- returning response 63 | ``` 64 | 65 | HTTP リクエストのプロキシに成功しました!! 66 | -------------------------------------------------------------------------------- /src/02_execution/01_chapter.md: -------------------------------------------------------------------------------- 1 | # 中身を見てみよう: Future と Task の実行 2 | 3 | このセクションでは,`Future`および非同期タスクがどのようにスケジューリングされるのか基本的は構造について説明します。 4 | 5 | 既存の`Future`型を使用してのハイレベルなコードの記述方法に興味があり、`Future`型の動作の詳細に興味がない場合は、[`async / await`](../03_async_await/01_chapter.md)の章へ進んでください。 6 | 7 | しかし!この章の内容のいくつかは、`async / await`コードがどのように動作するのか理解するのに役立ちますよ。`async / await`コードが動作するランタイム及びパフォーマンス特性を理解し、新しい非同期プリミティブを作成します。 8 | 9 | この章をスキップするなら、将来のためにブックマークすることをオススメします。 10 | 11 | さて、それが完了したなら`Future`トレイトについてお話していきましょうか。 12 | -------------------------------------------------------------------------------- /src/02_execution/02_future.md: -------------------------------------------------------------------------------- 1 | # Future トレイト 2 | 3 | `Future`トレイトは Rust の非同期プログラミングの中心人物です。(超重役だぞ!) 4 | 5 | `Future`は値を生成できる非同期計算です。(`()`のような空の値の時もあります) 6 | 7 | _簡略化した_`Future`トレイトは以下のようになります。 8 | 9 | ```rust 10 | {{#include ../../examples/02_02_future_trait/src/lib.rs:simple_future}} 11 | ``` 12 | 13 | この`poll`関数を呼び出すことで`Future`を進めることが出来ます、これにより、`Future`が可能な限り完了するようになります。`Future`が完了すると`Poll::Ready(result)`を返し、未完了のときは`Poll::Pending`を返して、`Future`がさらに進む準備ができたときに`wake()`関数が呼び出されるように準備します。 14 | 15 | `wake()`が呼び出されると、`Future`を駆動するエグゼキューターが`poll`を再度呼び出し、`Future`を更に進めようとします。 16 | 17 | `wakte()`がなければ、エグゼキューターは`Future`がいつ進むかを知る方法がなく、つねにすべての`future`をポーリングする必要があります。`wake()`を使用することで、エグゼキューターはどの`Future`を`poll`する準備ができているかを正確に把握できます。 18 | 19 | 例えば、すでに利用可能なデータが有る場合とない場合があるソケットから読み取りたい場合を考えます。データが有る場合、`Poll::Ready(data)`でそれを読み込んで返すことが出来ます。 20 | しかし、データの準備ができていない時`Future`はブロックされ、進行できなくなります。 21 | データが利用できない時、ソケットでデータの準備ができた時に`wake`が呼び出されるように登録する必要があります。 22 | これにより、エグゼキューターに準備が整ったことが分かります。 23 | 24 | 単純な`SocketRead`は次のようになります。 25 | 26 | ```rust 27 | {{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}} 28 | ``` 29 | 30 | このモデルでは、中間割当を必要とせずに、複数の非同期オペレーションを一緒に構築できます。 次のように、複数の`Future`を実行したり、連鎖させたりすることは割当のないステートマシンを介して実装できます。 31 | 32 | ```rust 33 | {{#include ../../examples/02_02_future_trait/src/lib.rs:join}} 34 | ``` 35 | 36 | これは、個別の割当を必要とせずに複数の`Future`を同時に実行できる方法を示し、より効率的な非同期プログラムを可能にします。同様に、複数のシーケンシャル`Future`を次々に実行することもできます。 37 | 38 | ```rust 39 | {{#include ../../examples/02_02_future_trait/src/lib.rs:and_then}} 40 | ``` 41 | 42 | これらの例は複数の割り当てられたオブジェクトと深くネストされたコールバックを必要とせずに、`Future`トレイトを使用して非同期制御フローを表現する方法を示しています。 43 | 44 | 基本的な制御フローが終わったら、実際の`Future`トレイトと`SimpleFuture`がどのように異なるかを話します。 45 | 46 | ```rust 47 | {{#include ../../examples/02_02_future_trait/src/lib.rs:real_future}} 48 | ``` 49 | 50 | 気づきやすい最初の変更は`self`がもはや`&mut self`出ないことです。 51 | `Pin<&mut Self>`に変更されました。`Pin`については、[あとのセクション](../04_pinning/01_chapter.md)で詳しくお話します、が、現時点では、`Pin`によって固定した`Future`を作成できることを知っています。固定されたオブジェクトはフィールドなどにポインタを格納できます。`struct MyFut { a: i32, ptr_to_a: *const i32 }`のように。 52 | `async / await`を有効にするにはピン留めが必要になります。 53 | 54 | 次に、`wake: fn()`は`&mut Context<'_>'`に変更されました。 55 | `SimpleFuture`では関数ポインターの呼び出しを使用して、`Future`をポーリングすることをエグゼキューターに伝えました。しかし、`fn()`はサイズがゼロであるため、`wake`が呼ばれたことなどのデータを保存することができません。 56 | 57 | 実際は、Web サーバーのような複雑なアプリケーションには起動をすべて個別に管理する必要がある数千の異なる接続が存在する場合があります。 58 | この`Context`タイプは特定のタスクを起動するために使用できる`Waker`へのアクセスを提供することでこれを解決します。 59 | -------------------------------------------------------------------------------- /src/02_execution/03_wakeups.md: -------------------------------------------------------------------------------- 1 | # タスクを起こせ!Waker! 2 | 3 | `Future`は最初に`poll`された時に完了できないことがよくあります。これが発生した時、`Future`はさらに前進する準備ができたら再度ポーリングされるようにする必要があります。 4 | これは`Waker`型で行われます。 5 | 6 | `Future`がポーリングされるたびに、「タスク」の一部としてポーリングされます。 7 | タスクは、エグゼキューターに送信されたトップレベルの`Future`です。 8 | 9 | `Waker`は関連付けられたタスクを起動する必要があることをエグゼキューターに伝えるために使用できる`wake()`メソッドを提供します。 10 | 11 | `wake()`が呼び出された時、エグゼキューターは、`Waker`と関連するタスクが進む準備が出来たことを知っています。そして、再びポーリングする必要があることも。 12 | 13 | `Waker`は`clone()`も実装しているため、コピーして保存することが出来ます。 14 | 15 | `Waker`を使用して単純なタイマーを実装してみましょう! 16 | 17 | ## タイマー作成 18 | 19 | この例では、タイマーが作成された時に新しいスレッドを立て、必要な時間だけスリープし、時間経過した時にタイマーの`Future`を通知します。 20 | 21 | 必要なインポートは次のとおりです。 22 | 23 | ```rust 24 | {{#include ../../examples/02_03_timer/src/lib.rs:imports}} 25 | ``` 26 | 27 | `Future`の型自体を定義するところからです。私達の future にはスレッドが、タイマーが経過し、future が完了するべきであることを伝える方法が必要です。 `Arc>`を使用して、スレッドと future の間で通信します。 28 | 29 | ```rust 30 | {{#include ../../examples/02_03_timer/src/lib.rs:timer_decl}} 31 | ``` 32 | 33 | 実際に`Future`の実装を書いていきましょう! 34 | 35 | ```rust 36 | {{#include ../../examples/02_03_timer/src/lib.rs:future_for_timer}} 37 | ``` 38 | 39 | かなり簡単ですね。スレッドに`shared_state.completed = true`が設定されている時、完了です! それ以外の場合`Waker`は現在のタスクのクローンを作成して`shared_state.waker`に渡し、スレッドがタスクを復帰できるようにします。 40 | 41 | 重要なのは、future が異なる`Waker`を持つ異なるタスクに移動した可能性があるため、future がポーリングされるたびに`Waker`を更新する必要があることです。これは、ポーリングされたあと、タスク間で future が渡される時に発生します。 42 | 43 | 最後に、実際にタイマーを構築してスレッドを開始する API が必要です。 44 | 45 | ```rust 46 | {{#include ../../examples/02_03_timer/src/lib.rs:timer_new}} 47 | ``` 48 | 49 | すげぇ!単純なタイマーの future を構築するために必要なのはそれだけです。 50 | さて、future を実行するエグゼキューターがいれば、、、 51 | -------------------------------------------------------------------------------- /src/02_execution/04_executor.md: -------------------------------------------------------------------------------- 1 | # エグゼキューターを書いてみよう 2 | 3 | Rust の`Future`は怠け者です。積極的に完了しない限り、何もしてくれません。 4 | future を完了させるための一つの方法は`async`関数内の`.await`です。 5 | それは問題は 1 レベル上に押し上げるだけです。トップレベルの非同期関数から返された future を誰が実行しますか? 6 | `Future`のエグゼキューターが必要です。 7 | 8 | `Future`エグゼキューターは、トップレベルの`Future`セットを取得し、`Future`が進行するたびに`poll`を呼び出すことにより、それらを完了まで実行します。 9 | 10 | 通常、エグゼキューターは future を一回`poll`して開始します。`Future`が`wake()`を呼び出して進行する準備ができたことを示すと、それらはキューに戻され、`poll`が再度呼び出され、`Future`が完了するまで繰り返されます。 11 | 12 | このセクションでは、多数のトップレベル future を同時に実行できる、独自のシンプルなエグゼキューターを作成していきます。 13 | 14 | この例では、`Waker`を構築する簡単な方法を提供する`ArcWake`トレイトの future クレートに依存しています。 15 | 16 | ```toml 17 | [package] 18 | name = "xyz" 19 | version = "0.1.0" 20 | authors = ["XYZ Author"] 21 | edition = "2018" 22 | 23 | [dependencies] 24 | futures-preview = "=0.3.0-alpha.17" 25 | ``` 26 | 27 | 次に、`src/main.rs`の先頭に次のインポートが必要です。 28 | 29 | ```rust 30 | {{#include ../../examples/02_04_executor/src/lib.rs:imports}} 31 | ``` 32 | 33 | エグゼキューターはチャネルを介して実行するタスクを送信することで動作します。エグゼキューターはチャネルからイベントを取得して実行します。タスクがより多くの作業をする準備ができた時に(起こされた時)、タスクをチャネルに戻すことにより、再度ポーリングされるようにスケジュールできます。 34 | 35 | この設計では、エグゼキューター自体にタスクチャネルの受信側が必要です。ユーザーは新しい future を作成できるように送信側を取得します。タスク自体は自分自身を再スケジュールする future です。 36 | したがって、タスク自体をリキューするために使用できる送信者とペアになった future として保存します。 37 | 38 | ```rust 39 | {{#include ../../examples/02_04_executor/src/lib.rs:executor_decl}} 40 | ``` 41 | 42 | また、spawner にメソッドを追加して、新しい future を簡単に生成できるようにします。このメソッドは future の型を取得し、それを box 化して`FutureObj`に入れ、その中にエグゼキューターにエンキューできる新しい`Arc`を作成します。 43 | 44 | ```rust 45 | {{#include ../../examples/02_04_executor/src/lib.rs:spawn_fn}} 46 | ``` 47 | 48 | future を poll するには`Waker`を作成する必要があります。[Waker の章](./03_wakeups.md)でも説明したように`Waker`は`wake()`が呼び出された時に再度ポーリングされるタスクをスケジュールする責任があります。`Waker`はどのタスクが準備完了になったかをエグゼキューターに正確に伝え、準備ができている future だけをポーリングできることを忘れないでください。新しい`Waker`を作成する簡単な方法は`ArcWake`トレイトを実装し、`waker_ref`または`.into_waker()`関数を使用して`Arc`を`Waker`に変更することです。タスクに`ArcWake`を実装してタスクを`Waker`に変えて目覚めさせてみましょう。 49 | 50 | ```rust 51 | {{#include ../../examples/02_04_executor/src/lib.rs:arcwake_for_task}} 52 | ``` 53 | 54 | `Arc`から`Waker`が作成された時に`wake()`を呼び出すと、Arc のコピーがタスクチャネルに送信されます。次に、エグゼキューターがタスクを取得してポーリングする必要があります。それを実装しましょう。 55 | 56 | ```rust 57 | {{#include ../../examples/02_04_executor/src/lib.rs:executor_run}} 58 | ``` 59 | 60 | おめでとう!future エグゼキューターができました!これを使用して、`async / .await`コードと先ほど書いた`TimerFuture`などのカスタム future を実行することができます。 61 | 62 | ```rust 63 | {{#include ../../examples/02_04_executor/src/lib.rs:main}} 64 | ``` 65 | -------------------------------------------------------------------------------- /src/02_execution/05_io.md: -------------------------------------------------------------------------------- 1 | # エグゼキューターとシステム IO 2 | 3 | 前の[Future トレイトの章](./02_future.md)でソケットで非同期読み取りを実行した Future の例を説明しました。 4 | 5 | ```rust 6 | {{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}} 7 | ``` 8 | 9 | この future はソケット上の利用可能なデータを読み取り、データが利用できない場合エグゼキューターに譲り、ソケットが再び読み取り可能になった時にタスクが起動されるように要求します。この例から`Socket`型がどのように実装されているかは明確ではなく、特に`set_readable_callback`関数がどのように機能するかは明らかでありません。 10 | 11 | ソケットが読み取り可能になったら`lw.wake()`が呼び出されるようにするにはどうすればよいですか? 1 つのオプションは`socket`が読み取り可能かどうかを継続的にチェックし、適切な時に`wake`を呼び出すスレッドを持つことです。 12 | 13 | ただし、これは非常に非効率でブロックされた IO ごとに個別のスレッドが必要になります。これにより、非同期コードの効率が大幅に低下します。 14 | 15 | 実際にはこの問題は、Linux の`epoll`、FreeBSD の`kqueue`及び、MacOS,Windows の IOCP、Fuchsia の port などの IO 対応システムブロックプリミティブとの統合によって解決されます。(これらはすべてクロスプラットフォームの Rust クレート[`mio`](https://github.com/tokio-rs/mio)を通じで公開されます。) 16 | これらのプリミティブはすべて、スレッドが複数の非同期 IO イベントでブロックすることを許可し、イベントの 1 つが完了すると戻ります。 17 | 18 | これらの API は通常以下のようになります。 19 | 20 | ```rust 21 | struct IoBlocker { 22 | ... 23 | } 24 | 25 | struct Event { 26 | // 発生し、リッスンされたイベントを一意に識別するID 27 | id: usize, 28 | 29 | // 待機、または発生したシグナルのセット 30 | signals: Signals, 31 | } 32 | 33 | impl IoBlocker { 34 | /// ブロックする非同期IOイベントの新しいコレクションを作成 35 | fn new() -> Self { ... } 36 | 37 | fn add_io_event_interest( 38 | &self, 39 | 40 | /// イベントが発火するオブジェクト 41 | io_object: &IoObject, 42 | 43 | /// イベントをトリガーするio_objectに表示される可能性のあるシグナルのセット 44 | /// この関心から生じるイベントに与えるIDとペアになります。 45 | event: Event, 46 | ) { ... } 47 | 48 | /// イベントの1つが発生するまでブロックします 49 | fn block(&self) -> Event { ... } 50 | } 51 | 52 | let mut io_blocker = IoBlocker::new(); 53 | io_blocker.add_io_event_interest( 54 | &socket_1, 55 | Event { id: 1, signals: READABLE }, 56 | ); 57 | io_blocker.add_io_event_interest( 58 | &socket_2, 59 | Event { id: 2, signals: READABLE | WRITABLE }, 60 | ); 61 | let event = io_blocker.block(); 62 | 63 | println!("Socket {:?} is now {:?}", event.id, event.signals); 64 | ``` 65 | 66 | Future エグゼキューターは、これらのプリミティブを使用して、特定の IO イベントが発生した時に実行されるコールバックを構成できるソケットなどの非同期 IO オブジェクトを提供できます。 67 | 68 | 上記の`SocketRead`の場合`Socket::set_readable_callback`関数は次のような擬似コードのようになります。 69 | 70 | ```rust 71 | impl Socket { 72 | fn set_readable_callback(&self, waker: Waker) { 73 | // local_executorはローカルエグゼキューターへの参照です 74 | // これは、ソケットの作成時に提供できますが 75 | // 実際には多くのエグゼキューターの実装は、 76 | // 便宜上、スレッドローカルストレージを介してそれを渡します。 77 | let local_executor = self.local_executor; 78 | 79 | // このIOオブジェクトのID 80 | let id = self.id; 81 | 82 | // Store the local waker in the executor's map so that it can be called 83 | // once the IO event arrives. 84 | // IOイベントが到着したら呼び出せるようにローカルwakerをエグゼキューターのマップに保存します。 85 | local_executor.event_map.insert(id, waker); 86 | local_executor.add_io_event_interest( 87 | &self.socket_file_descriptor, 88 | Event { id, signals: READABLE }, 89 | ); 90 | } 91 | } 92 | ``` 93 | 94 | IO イベントを受信して適切な`Waker`タスクにディスパッチできるエグゼキュータースレッドを一つだけ持つことができるようになりました。 95 | -------------------------------------------------------------------------------- /src/03_async_await/01_chapter.md: -------------------------------------------------------------------------------- 1 | # async/await 再び! 2 | -------------------------------------------------------------------------------- /src/04_pinning/01_chapter.md: -------------------------------------------------------------------------------- 1 | # pin で固定しよう 2 | -------------------------------------------------------------------------------- /src/05_streams/01_chapter.md: -------------------------------------------------------------------------------- 1 | # ストリーーム 2 | -------------------------------------------------------------------------------- /src/05_streams/02_iteration_and_concurrency.md: -------------------------------------------------------------------------------- 1 | # イテレーションと並行性 2 | -------------------------------------------------------------------------------- /src/06_multiple_futures/01_chapter.md: -------------------------------------------------------------------------------- 1 | # たくさんの Future を一度に実行しよう 2 | -------------------------------------------------------------------------------- /src/06_multiple_futures/02_join.md: -------------------------------------------------------------------------------- 1 | # join マクロ 2 | -------------------------------------------------------------------------------- /src/06_multiple_futures/03_select.md: -------------------------------------------------------------------------------- 1 | # select マクロ 2 | -------------------------------------------------------------------------------- /src/07_workarounds/01_chapter.md: -------------------------------------------------------------------------------- 1 | # Workarounds to Know and Love 2 | -------------------------------------------------------------------------------- /src/07_workarounds/02_return_type.md: -------------------------------------------------------------------------------- 1 | # 戻り型エラー 2 | -------------------------------------------------------------------------------- /src/07_workarounds/03_err_in_async_blocks.md: -------------------------------------------------------------------------------- 1 | # async ブロックでの?オペレーション 2 | -------------------------------------------------------------------------------- /src/07_workarounds/04_send_approximation.md: -------------------------------------------------------------------------------- 1 | # Send Approximation 2 | -------------------------------------------------------------------------------- /src/07_workarounds/05_recursion.md: -------------------------------------------------------------------------------- 1 | # 再帰、再帰、再帰 2 | -------------------------------------------------------------------------------- /src/07_workarounds/06_async_in_traits.md: -------------------------------------------------------------------------------- 1 | # Traits での async 2 | -------------------------------------------------------------------------------- /src/404.md: -------------------------------------------------------------------------------- 1 | # まだ: The Ecosystem: Tokio and More 2 | -------------------------------------------------------------------------------- /src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of Contents 2 | 3 | - [はじめに](01_getting_started/01_chapter.md) 4 | - [なぜ非同期?](01_getting_started/02_why_async.md) 5 | - [非同期 Rust の現状](01_getting_started/03_state_of_async_rust.md) 6 | - [`async`/`.await` 入門書!](01_getting_started/04_async_await_primer.md) 7 | - [HTTP サーバーを書いてみよう!](01_getting_started/05_http_server_example.md) 8 | - [中身を見てみよう: `Future`と`Task`の実行](02_execution/01_chapter.md) 9 | - [`Future`トレイト](02_execution/02_future.md) 10 | - [タスクを起こせ!`Waker`!](02_execution/03_wakeups.md) 11 | - [エグゼキューターを書いてみよう](02_execution/04_executor.md) 12 | - [エグゼキューターとシステム IO](02_execution/05_io.md) 13 | - [`async`/`await`再び!](03_async_await/01_chapter.md) 14 | - [pin で固定しよう](04_pinning/01_chapter.md) 15 | - [ストリーム](05_streams/01_chapter.md) 16 | - [イテレーションと並行性](05_streams/02_iteration_and_concurrency.md) 17 | - [たくさんの Future を一度に実行しよう](06_multiple_futures/01_chapter.md) 18 | - [`join`マクロ](06_multiple_futures/02_join.md) 19 | - [`select`マクロ](06_multiple_futures/03_select.md) 20 | - [まだ書けてない: Spawning](404.md) 21 | - [まだ書けてない: キャンセルとタイムアウト](404.md) 22 | - [まだ書けてない: `FuturesUnordered`](404.md) 23 | - [Workarounds to Know and Love](07_workarounds/01_chapter.md) 24 | - [戻り型エラー](07_workarounds/02_return_type.md) 25 | - [`async`ブロックでの`?`オペレーション](07_workarounds/03_err_in_async_blocks.md) 26 | - [`Send` Approximation](07_workarounds/04_send_approximation.md) 27 | - [再帰、再帰、再帰](07_workarounds/05_recursion.md) 28 | - [Traits での`async`](07_workarounds/06_async_in_traits.md) 29 | - [まだ書けてない: I/O](404.md) 30 | - [まだ: `AsyncRead`と`AsyncWrite`](404.md) 31 | - [まだ: 非同期デザインパターン: 解決法と提案](404.md) 32 | - [まだ: Modeling Servers and the Request/Response Pattern](404.md) 33 | - [まだ: Managing Shared State](404.md) 34 | - [まだ: The Ecosystem: Tokio and More](404.md) 35 | - [まだ: Lots, lots more?...](404.md) 36 | -------------------------------------------------------------------------------- /src/chapter_1.md: -------------------------------------------------------------------------------- 1 | # Chapter 1 2 | --------------------------------------------------------------------------------