Creating Your Own Runtime 252 The only thing you need is Rust installed and the book's repository downloaded locally. All the code in this chapter can be found in the ch10 folder. We'll use delayserver in this example as well, so you need to open a separate terminal, enter the delayserver folder at the root of the repository, and type cargo run so it's ready and available for the examples going forward. Remember to change the ports in the code if for some reason you have to change what port delayserver listens on. Creating our own runtime with futures and async/await Okay, so we're in the home stretch; the last thing we'll do is change our runtime so it uses the Rust Future trait, Waker, and async/await. This will be a relatively easy task for us now that we've pretty much covered the most complex aspects of asynchronous programming in Rust by building everything up ourselves. We have even gone into quite some detail on the design decisions that Rust had to make along the way. The asynchronous programming model Rust has today is the result of an evolutionary process. Rust started in its early stages with green threads, but this was before it reached version 1. 0. At the point of reaching version 1. 0, Rust didn't have the notion of futures or asynchronous operations in its standard library at all. This space was explored on the side in the futures-rs crate ( https://github. com/ rust-lang/futures-rs ), which still serves as a nursery for async abstractions today. However, it didn't take long before Rust settled around a version of the Future trait similar to what we have today, often referred to as futures 0. 1. Supporting coroutines created by async/await was something that was in the works already at that point but it took a few years before the design reached its final stage and entered the stable version of the standard library. So, many of the choices we had to make with our async implementation are real choices that Rust had to make along the way. However, it all brings us to this point, so let's get to it and start adapting our runtime so it works with Rust futures. Before we get to the example, let's cover the things that are different from our current implementation: The Future trait Rust uses is slightly different from what we have now. The biggest difference is that it takes something called Context instead of Waker. The other difference is that it returns an enum called Poll instead of Poll State. Context is a wrapper around Rust's Waker type. Its only purpose is to future-proof the API so it can hold additional data in the future without having to change anything related to Waker. The Poll enum returns one of two states, Ready(T) or Pending. This is slightly different from what we have now with our Poll State enum, but the two states mean the same as Ready(T)/Not Ready in our current implementation. Wakers in Rust is slightly more complex to create than what we're used to with our current Waker. We'll go through how and why later in the chapter.