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}