aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-24 06:30:57 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-24 06:30:57 -0400
commitec954d2ce33de2fc59544cb9824b34c28d72dace (patch)
treee6fee919da7a62c942b197ffef4d38157eed6c13
parentf6d4219c8edb60741d5a5596b097ebb9722d04fc (diff)
downloadcomponent-future-ec954d2ce33de2fc59544cb9824b34c28d72dace.tar.gz
component-future-ec954d2ce33de2fc59544cb9824b34c28d72dace.zip
add various crate metadata0.1.0
-rw-r--r--Cargo.toml7
-rw-r--r--LICENSE32
-rw-r--r--README.md81
-rw-r--r--src/lib.rs5
4 files changed, 125 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index ed883db..bbd4688 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,13 @@ version = "0.1.0"
authors = ["Jesse Luehrs <doy@tozt.net>"]
edition = "2018"
+description = "implements the inner future protocol documented in the tokio docs"
+license = "MIT"
+repository = "https://git.tozt.net/component-future"
+readme = "README.md"
+keywords = ["futures"]
+categories = ["asynchronous", "rust-patterns"]
+
[dependencies]
futures = "0.1"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..fda0fd2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,32 @@
+This software is Copyright (c) 2019 by Jesse Luehrs.
+
+This is free software, licensed under:
+
+ The MIT (X11) License
+
+The MIT License
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to
+whom the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice shall
+be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
+WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
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)
+ }
+}
+```
diff --git a/src/lib.rs b/src/lib.rs
index cf21031..e3ee46a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -89,10 +89,15 @@
//! }
//! ```
+// XXX this is broken with ale
+// #![warn(clippy::cargo)]
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
+#![allow(clippy::multiple_crate_versions)]
#![allow(clippy::type_complexity)]
+const _DUMMY_DEPENDENCY: &str = include_str!("../Cargo.toml");
+
/// Return type of a component of a future or stream, indicating whether a
/// value is ready, or if not, what actions were taken.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]