diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/futures-0.1.31/src/future/lazy.rs | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/futures-0.1.31/src/future/lazy.rs')
-rw-r--r-- | third_party/rust/futures-0.1.31/src/future/lazy.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/third_party/rust/futures-0.1.31/src/future/lazy.rs b/third_party/rust/futures-0.1.31/src/future/lazy.rs new file mode 100644 index 0000000000..2f310337b6 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/lazy.rs @@ -0,0 +1,84 @@ +//! Definition of the Lazy combinator, deferring execution of a function until +//! the future is polled. + +use core::mem; + +use {Future, IntoFuture, Poll}; + +/// A future which defers creation of the actual future until a callback is +/// scheduled. +/// +/// This is created by the `lazy` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Lazy<F, R: IntoFuture> { + inner: _Lazy<F, R::Future>, +} + +#[derive(Debug)] +enum _Lazy<F, R> { + First(F), + Second(R), + Moved, +} + +/// Creates a new future which will eventually be the same as the one created +/// by the closure provided. +/// +/// The provided closure is only run once the future has a callback scheduled +/// on it, otherwise the callback never runs. Once run, however, this future is +/// the same as the one the closure creates. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let a = lazy(|| ok::<u32, u32>(1)); +/// +/// let b = lazy(|| -> FutureResult<u32, u32> { +/// panic!("oh no!") +/// }); +/// drop(b); // closure is never run +/// ``` +pub fn lazy<F, R>(f: F) -> Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture +{ + Lazy { + inner: _Lazy::First(f), + } +} + +impl<F, R> Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture, +{ + fn get(&mut self) -> &mut R::Future { + match self.inner { + _Lazy::First(_) => {} + _Lazy::Second(ref mut f) => return f, + _Lazy::Moved => panic!(), // can only happen if `f()` panics + } + match mem::replace(&mut self.inner, _Lazy::Moved) { + _Lazy::First(f) => self.inner = _Lazy::Second(f().into_future()), + _ => panic!(), // we already found First + } + match self.inner { + _Lazy::Second(ref mut f) => f, + _ => panic!(), // we just stored Second + } + } +} + +impl<F, R> Future for Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture, +{ + type Item = R::Item; + type Error = R::Error; + + fn poll(&mut self) -> Poll<R::Item, R::Error> { + self.get().poll() + } +} |