aboutsummaryrefslogtreecommitdiffstats
path: root/tests/basic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/basic.rs')
-rw-r--r--tests/basic.rs206
1 files changed, 206 insertions, 0 deletions
diff --git a/tests/basic.rs b/tests/basic.rs
new file mode 100644
index 0000000..8cfebcd
--- /dev/null
+++ b/tests/basic.rs
@@ -0,0 +1,206 @@
+extern crate component_future;
+
+mod run;
+
+#[test]
+fn test_basic_future() {
+ struct TwoFutures {
+ fut1: Option<
+ Box<
+ dyn futures::future::Future<Item = u32, Error = String>
+ + Send,
+ >,
+ >,
+ fut2: Option<
+ Box<
+ dyn futures::future::Future<Item = u32, Error = String>
+ + Send,
+ >,
+ >,
+ val: u32,
+ }
+
+ impl TwoFutures {
+ fn new<F1, F2>(fut1: F1, fut2: F2) -> Self
+ where
+ F1: futures::future::Future<Item = u32, Error = String>
+ + Send
+ + 'static,
+ F2: futures::future::Future<Item = u32, Error = String>
+ + Send
+ + 'static,
+ {
+ Self {
+ fut1: Some(Box::new(fut1)),
+ fut2: Some(Box::new(fut2)),
+ val: 1,
+ }
+ }
+ }
+
+ #[allow(clippy::type_complexity)]
+ impl TwoFutures {
+ const POLL_FNS:
+ &'static [&'static dyn for<'a> Fn(
+ &'a mut Self,
+ )
+ -> component_future::Poll<
+ u32,
+ String,
+ >] = &[
+ &Self::poll_future_1,
+ &Self::poll_future_2,
+ &Self::poll_return,
+ ];
+
+ fn poll_future_1(&mut self) -> component_future::Poll<u32, String> {
+ if let Some(fut1) = &mut self.fut1 {
+ let val = component_future::try_ready!(fut1.poll());
+ self.val += val;
+ self.fut1.take();
+ Ok(component_future::Async::DidWork)
+ } else {
+ Ok(component_future::Async::NothingToDo)
+ }
+ }
+
+ fn poll_future_2(&mut self) -> component_future::Poll<u32, String> {
+ if self.fut1.is_some() {
+ return Ok(component_future::Async::NothingToDo);
+ }
+
+ if let Some(fut2) = &mut self.fut2 {
+ let val = component_future::try_ready!(fut2.poll());
+ self.val *= val;
+ self.fut2.take();
+ Ok(component_future::Async::DidWork)
+ } else {
+ Ok(component_future::Async::NothingToDo)
+ }
+ }
+
+ fn poll_return(&mut self) -> component_future::Poll<u32, String> {
+ if self.fut1.is_some() || self.fut2.is_some() {
+ return Ok(component_future::Async::NothingToDo);
+ }
+
+ Ok(component_future::Async::Ready(self.val))
+ }
+ }
+
+ impl futures::future::Future for TwoFutures {
+ type Item = u32;
+ type Error = String;
+
+ fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
+ component_future::poll_future(self, Self::POLL_FNS)
+ }
+ }
+
+ let cfut =
+ TwoFutures::new(futures::future::ok(3), futures::future::ok(5));
+ let i = run::future(cfut);
+ assert_eq!(i, Ok(20));
+}
+
+#[test]
+fn test_basic_stream() {
+ struct TwoFutures {
+ fut1: Option<
+ Box<
+ dyn futures::future::Future<Item = u32, Error = String>
+ + Send,
+ >,
+ >,
+ fut2: Option<
+ Box<
+ dyn futures::future::Future<Item = u32, Error = String>
+ + Send,
+ >,
+ >,
+ }
+
+ impl TwoFutures {
+ fn new<F1, F2>(fut1: F1, fut2: F2) -> Self
+ where
+ F1: futures::future::Future<Item = u32, Error = String>
+ + Send
+ + 'static,
+ F2: futures::future::Future<Item = u32, Error = String>
+ + Send
+ + 'static,
+ {
+ Self {
+ fut1: Some(Box::new(fut1)),
+ fut2: Some(Box::new(fut2)),
+ }
+ }
+ }
+
+ impl TwoFutures {
+ #[allow(clippy::type_complexity)]
+ const POLL_FNS:
+ &'static [&'static dyn for<'a> Fn(
+ &'a mut Self,
+ )
+ -> component_future::Poll<
+ Option<u32>,
+ String,
+ >] = &[
+ &Self::poll_future_1,
+ &Self::poll_future_2,
+ &Self::poll_return,
+ ];
+
+ fn poll_future_1(
+ &mut self,
+ ) -> component_future::Poll<Option<u32>, String> {
+ if let Some(fut1) = &mut self.fut1 {
+ let val = component_future::try_ready!(fut1.poll());
+ self.fut1.take();
+ Ok(component_future::Async::Ready(Some(val)))
+ } else {
+ Ok(component_future::Async::NothingToDo)
+ }
+ }
+
+ fn poll_future_2(
+ &mut self,
+ ) -> component_future::Poll<Option<u32>, String> {
+ if self.fut1.is_some() {
+ return Ok(component_future::Async::NothingToDo);
+ }
+
+ if let Some(fut2) = &mut self.fut2 {
+ let val = component_future::try_ready!(fut2.poll());
+ self.fut2.take();
+ Ok(component_future::Async::Ready(Some(val)))
+ } else {
+ Ok(component_future::Async::NothingToDo)
+ }
+ }
+
+ fn poll_return(
+ &mut self,
+ ) -> component_future::Poll<Option<u32>, String> {
+ if self.fut1.is_some() || self.fut2.is_some() {
+ return Ok(component_future::Async::NothingToDo);
+ }
+
+ Ok(component_future::Async::Ready(None))
+ }
+ }
+
+ impl futures::stream::Stream for TwoFutures {
+ type Item = u32;
+ type Error = String;
+
+ fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> {
+ component_future::poll_stream(self, Self::POLL_FNS)
+ }
+ }
+ let cstream =
+ TwoFutures::new(futures::future::ok(3), futures::future::ok(5));
+ let is = run::stream(cstream);
+ assert_eq!(is, Ok(vec![3, 5]));
+}