Skip to main content

qubit_io/async_io/
write_future.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9use std::future::Future;
10use std::io::Result;
11use std::pin::Pin;
12use std::task::Context;
13use std::task::Poll;
14
15use crate::AsyncOutput;
16
17/// Future for one [`AsyncOutput`] write operation.
18///
19/// # Panics
20///
21/// [`Future::poll`] panics when called again after this future has returned
22/// [`Poll::Ready`].
23///
24/// # Type Parameters
25///
26/// - `'a`: Shared lifetime of the output borrow and source slice.
27/// - `O`: Asynchronous output type.
28#[must_use = "futures do nothing unless polled"]
29pub struct WriteFuture<'a, O>
30where
31    O: AsyncOutput + ?Sized,
32{
33    /// Output being written.
34    output: Pin<&'a mut O>,
35    /// Source for the write.
36    input: &'a [O::Item],
37    /// Whether the write operation has completed.
38    completed: bool,
39}
40
41impl<'a, O> WriteFuture<'a, O>
42where
43    O: AsyncOutput + ?Sized,
44{
45    /// Creates a write future from a pinned output.
46    ///
47    /// # Parameters
48    ///
49    /// - `output`: Pinned asynchronous output.
50    /// - `input`: Source storage.
51    ///
52    /// # Returns
53    ///
54    /// Returns a future representing one write operation.
55    #[inline(always)]
56    pub const fn new(output: Pin<&'a mut O>, input: &'a [O::Item]) -> Self {
57        Self {
58            output,
59            input,
60            completed: false,
61        }
62    }
63}
64
65impl<O> Future for WriteFuture<'_, O>
66where
67    O: AsyncOutput + ?Sized,
68{
69    /// Item count produced when the write becomes ready.
70    type Output = Result<usize>;
71
72    /// Polls the write operation.
73    ///
74    /// # Parameters
75    ///
76    /// - `cx`: Task context used to register a wake-up.
77    ///
78    /// # Returns
79    ///
80    /// Returns [`Poll::Pending`] when the output is not ready. A ready success
81    /// contains the number of items accepted.
82    ///
83    /// # Errors
84    ///
85    /// Returns an I/O error reported by the output.
86    ///
87    /// # Panics
88    ///
89    /// Panics when polled after returning [`Poll::Ready`].
90    #[inline]
91    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
92        let this = self.get_mut();
93        assert!(!this.completed, "WriteFuture polled after completion");
94        let result = this.output.as_mut().poll_write(cx, this.input);
95        if result.is_ready() {
96            this.completed = true;
97        }
98        result
99    }
100}