diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-10-24 06:30:57 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-10-24 06:30:57 -0400 |
commit | ec954d2ce33de2fc59544cb9824b34c28d72dace (patch) | |
tree | e6fee919da7a62c942b197ffef4d38157eed6c13 /README.md | |
parent | f6d4219c8edb60741d5a5596b097ebb9722d04fc (diff) | |
download | component-future-ec954d2ce33de2fc59544cb9824b34c28d72dace.tar.gz component-future-ec954d2ce33de2fc59544cb9824b34c28d72dace.zip |
add various crate metadata0.1.0
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..408f564 --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +# component-future + +This crate implements the inner future protocol documented in +[the tokio docs](https://tokio.rs/docs/futures/getting_asynchronous/). + +## Overview + +If you are implementing a complicated future or stream which contains many +inner futures and streams, it can be difficult to keep track of when looping +is necessary, when it is safe to return `NotReady`, etc. This provides an +interface similar to the existing `poll` interface for futures and streams, +but extended to include additional state about how the inner future or stream +affected the outer future or stream's state. This allows you to easily split +your `poll` implementation into multiple methods, and ensure that they +interact properly. + +## Synopsis + +```rust +enum OutputEvent { + // ... +} + +struct Server { + // ... +} + +impl Server { + fn process_thing(&self, thing: OutputEvent) { + // ... + } + + fn process_other_thing(&self, thing: OutputEvent) -> OutputEvent { + // ... + } +} + +impl Server { + const POLL_FNS: + &'static [&'static dyn for<'a> Fn( + &'a mut Self, + ) + -> component_future::Poll< + Option<OutputEvent>, + String, + >] = &[&Self::poll_thing, &Self::poll_other_thing]; + + fn poll_thing( + &mut self, + ) -> component_future::Poll<Option<OutputEvent>, String> { + let thing = component_future::try_ready!(self.some_future.poll()); + self.process_thing(thing); + Ok(component_future::Async::DidWork) + } + + fn poll_other_thing( + &mut self, + ) -> component_future::Poll<Option<OutputEvent>, String> { + if let Some(other_future) = &mut self.other_future { + let other_thing = component_future::try_ready!( + other_future.poll() + ); + let processed_thing = self.process_other_thing(other_thing); + self.other_future.take(); + Ok(component_future::Async::Ready(Some(processed_thing))) + } + else { + Ok(component_future::Async::NothingToDo) + } + } +} + +impl futures::stream::Stream for Server { + type Item = OutputEvent; + type Error = String; + + fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> { + component_future::poll_stream(self, Self::POLL_FNS) + } +} +``` |