pub struct AsyncTranscodeEncodeOutput<O>{ /* private fields */ }Expand description
Buffers asynchronous transcoder output while preserving pending units.
This adapter is the asynchronous counterpart to
super::TranscodeEncodeOutput. It owns the unit-level buffer, so a
future cancelled while the wrapped output is pending retains every unit
that the transcoder has already produced. Each transcode operation returns
after exactly one encoder invocation, so its progress is the explicit
source-consumption commit boundary.
Cancellation and pending-output recovery assume that wrapped I/O calls obey their normal return contracts. This adapter does not track poisoning or indeterminate delivery after an inner I/O panic. If such a panic is caught, reconcile external side effects before retrying or replaying pending units.
§Type Parameters
O- Wrapped asynchronous unit output.
§Examples
use core::convert::Infallible;
use core::num::NonZeroUsize;
use std::future::Future;
use std::io::Result;
use std::pin::{pin, Pin};
use std::task::{Context, Poll, Waker};
use qubit_codec::{AsyncTranscodeEncodeOutput, Codec, CodecTranscodeEncoder};
use qubit_codec::{DecodeFailure, TranscodeEncoder};
use qubit_io::AsyncOutput;
struct ByteCodec;
impl Codec for ByteCodec {
type Value = u8;
type Unit = u8;
type DecodeError = Infallible;
type EncodeError = Infallible;
const MIN_UNITS_PER_VALUE: usize = 1;
const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
unsafe fn decode(&mut self, input: &[u8], index: usize)
-> std::result::Result<(u8, NonZeroUsize), DecodeFailure<Infallible>> {
Ok((input[index], NonZeroUsize::MIN))
}
unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
-> std::result::Result<usize, Infallible> {
output[index] = *value;
Ok(1)
}
}
#[derive(Default)]
struct Sink { bytes: Vec<u8>, flushes: usize }
impl AsyncOutput for Sink {
type Item = u8;
unsafe fn poll_write_unchecked(
self: Pin<&mut Self>, _: &mut Context<'_>, units: &[u8], index: usize, count: usize,
) -> Poll<Result<usize>> {
self.get_mut().bytes.extend_from_slice(&units[index..index + count]);
Poll::Ready(Ok(count))
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>> {
self.get_mut().flushes += 1;
Poll::Ready(Ok(()))
}
}
async fn run_example() -> Result<()> {
let mut encoder = CodecTranscodeEncoder::new(ByteCodec);
let mut output = AsyncTranscodeEncodeOutput::with_capacity(Sink::default(), 8);
let mut map_error = |_| std::io::Error::other("encode error");
output.reset_async(&mut encoder, &mut map_error).await?;
let values = [1_u8, 2, 3];
let mut offset = 0;
while offset < values.len() {
let progress = output.transcode_async(
&mut encoder, &mut map_error, &values, offset, values.len() - offset,
).await?;
assert!(progress.read() > 0);
offset += progress.read();
}
output.finish_async(&mut encoder, &mut map_error).await?;
assert_eq!(output.pending_len(), values.len());
output.flush_async().await?;
let (sink, pending) = output.into_parts();
assert!(pending.is_empty());
assert_eq!(sink.bytes, vec![1, 2, 3]);
assert_eq!(sink.flushes, 1);
Ok(())
}
let mut future = pin!(run_example());
let mut context = Context::from_waker(Waker::noop());
match future.as_mut().poll(&mut context) {
Poll::Ready(result) => result.unwrap(),
Poll::Pending => panic!("the example sink always completes immediately"),
}finish_async commits final units to the adapter buffer. flush_async
delivers those units and flushes the wrapped sink.
Implementations§
Source§impl<O> AsyncTranscodeEncodeOutput<O>
impl<O> AsyncTranscodeEncodeOutput<O>
Sourcepub fn new(inner: O) -> Self
pub fn new(inner: O) -> Self
Creates an asynchronous encoder output with the default unit capacity.
§Parameters
inner- Unit output receiving transcoder data.
§Returns
Returns a buffered asynchronous output adapter.
§Panics
Panics if initializing the default buffer requires O::Item::default()
or O::Item::clone() and either operation panics, or if the default
backing length exceeds Vec’s supported capacity.
Sourcepub fn with_capacity(inner: O, capacity: usize) -> Self
pub fn with_capacity(inner: O, capacity: usize) -> Self
Creates an asynchronous encoder output with at least capacity units.
§Parameters
inner- Unit output receiving transcoder data.capacity- Requested internal unit capacity.
§Returns
Returns a buffered asynchronous output adapter.
§Panics
Panics if initializing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics, or if the requested
backing length exceeds Vec’s supported capacity.
Sourcepub fn try_with_capacity(
inner: O,
capacity: usize,
) -> Result<Self, TryReserveError>
pub fn try_with_capacity( inner: O, capacity: usize, ) -> Result<Self, TryReserveError>
Tries to create an adapter with at least capacity buffered units.
§Parameters
inner- Output moved into the adapter, including on allocation failure.capacity- Minimum number of units to reserve.
§Returns
Returns an empty buffered adapter on successful allocation.
§Errors
Returns an allocation error when the internal unit buffer cannot be allocated.
§Panics
Panics if initializing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the total internal unit-buffer capacity.
§Returns
The allocated unit capacity, including occupied and spare slots.
Sourcepub const fn inner(&self) -> &O
pub const fn inner(&self) -> &O
Returns a shared reference to the wrapped asynchronous output.
§Returns
Returns the wrapped output. Units can still be pending in this adapter.
Sourcepub fn inner_mut(&mut self) -> &mut O
pub fn inner_mut(&mut self) -> &mut O
Returns a mutable reference to the wrapped asynchronous output.
Pending adapter units are not automatically delivered before direct
output operations. Call Self::flush_async first when ordering with
previously transcoded data matters.
§Returns
Returns the wrapped output.
Sourcepub const fn pending_len(&self) -> usize
pub const fn pending_len(&self) -> usize
Returns the number of units retained pending delivery.
§Returns
Returns the length of the pending unit window.
Sourcepub fn into_parts(self) -> (O, Buffer<O::Item>)
pub fn into_parts(self) -> (O, Buffer<O::Item>)
Consumes this adapter without flushing the wrapped output.
This method performs no asynchronous I/O. The returned buffer holds units that must be delivered before the logical stream can continue.
Recovery assumes that wrapped I/O calls obey their normal return contracts. If an inner I/O panic is caught, the pending units may overlap a prefix already delivered. The buffer does not track this indeterminate delivery; reconcile external side effects before retrying or replaying those units.
§Returns
Returns the wrapped output and its pending unit buffer, assuming wrapped I/O calls obey their normal return contracts.
Source§impl<O> AsyncTranscodeEncodeOutput<O>
impl<O> AsyncTranscodeEncodeOutput<O>
Sourcepub async fn flush_async(&mut self) -> Result<()>
pub async fn flush_async(&mut self) -> Result<()>
Sourcepub async fn drain_async(&mut self) -> Result<()>
pub async fn drain_async(&mut self) -> Result<()>
Sourcepub async fn reset_async<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
) -> Result<()>
pub async fn reset_async<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, ) -> Result<()>
Runs encoder reset and buffers its stream-prefix units.
§Type Parameters
E- Encoder producing the wrapped output item type.M- Error mapper invoked for encoder failures.Value- Logical input value type accepted by the encoder.
§Parameters
encoder- Streaming encoder whose lifecycle is being started.map_error- Maps transcoder errors into I/O errors.
§Returns
Returns Ok(()) with the reset prefix retained in the buffer.
A successful reset discards the previous stream’s spare-capacity hint.
Previously committed pending units remain buffered in delivery order.
§Errors
Returns capacity planning, output delivery, allocation, or mapped reset errors. Pending units remain retained if asynchronous delivery fails.
§Panics
Panics when encoder writes more units than its declared reset bound.
Sourcepub fn poll_transcode<E, M, Value>(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
encoder: &mut E,
map_error: &mut M,
input: &[Value],
input_index: usize,
count: usize,
) -> Poll<Result<TranscodeProgress>>
pub fn poll_transcode<E, M, Value>( self: Pin<&mut Self>, cx: &mut Context<'_>, encoder: &mut E, map_error: &mut M, input: &[Value], input_index: usize, count: usize, ) -> Poll<Result<TranscodeProgress>>
Polls one cancellation-safe encoder operation.
The adapter may first deliver previously pending output to make a
conservative spare range available. Once it invokes encoder, it
advances the produced units and returns immediately without another
poll. The returned TranscodeProgress is therefore the exact source
range committed by this call.
§Type Parameters
E- Encoder producing the wrapped output item type.M- Error mapper invoked for encoder failures.Value- Logical input value type accepted by the encoder.
§Parameters
cx- Task context used by the sink to register readiness.encoder- Streaming encoder used for the conversion.map_error- Maps transcoder errors into I/O errors.input- Source values.input_index- First source value to transcode.count- Number of source values available frominput_index.
§Returns
Returns Pending while making output space, without consuming input,
or Ready with one validated encoder progress report or an error.
§Errors
Returns invalid input ranges, output delivery, allocation, contract, or mapped transcoder errors. Pending units remain retained after a failed asynchronous delivery. An encoder error does not provide general transactional rollback or complete progress: the encoder may already have advanced, but units written by its failing call are not committed to this adapter’s pending output. Do not replay the original input range unless the concrete encoder provides an explicit recovery protocol. Previously committed pending units follow the wrapped output’s recovery contract; reset starts a new logical stream and does not undo output already delivered.
Sourcepub async fn transcode_async<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
input: &[Value],
input_index: usize,
count: usize,
) -> Result<TranscodeProgress>
pub async fn transcode_async<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, input: &[Value], input_index: usize, count: usize, ) -> Result<TranscodeProgress>
Transcodes one cancellation-safe progress step into the retained buffer.
This is the async wrapper for Self::poll_transcode. It returns after
one encoder invocation; callers that need to consume a whole source
range must advance the source index by TranscodeProgress::read and
call it again.
§Type Parameters
E- Encoder producing the wrapped output item type.M- Error mapper invoked for encoder failures.Value- Logical input value type accepted by the encoder.
§Parameters
encoder- Encoder invoked once after output space is available.map_error- Maps encoder errors to I/O errors.input- Source values borrowed for this operation.input_index- Starting source offset.count- Number of source values available at that offset.
§Returns
One validated progress report describing committed source consumption.
§Errors
Returns range, capacity, allocation, delivery, contract or mapped
encoder errors, with pending units retained as described by
Self::poll_transcode.
Sourcepub async fn finish_async<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
) -> Result<()>
pub async fn finish_async<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, ) -> Result<()>
Finishes the encoder and retains its final output for delivery.
§Type Parameters
E- Encoder producing the wrapped output item type.M- Error mapper invoked for encoder failures.Value- Logical input value type accepted by the encoder.
§Parameters
encoder- Streaming encoder whose lifecycle is being finished.map_error- Maps transcoder errors into I/O errors.
§Returns
Returns Ok(()) after final units are committed to the buffer.
§Errors
Returns capacity planning, output delivery, allocation, or mapped finish
errors. Call Self::flush_async after this method to deliver
final units. Keeping finalization separate from delivery lets a
caller record the completed lifecycle before any later suspension
point.
§Panics
Panics when encoder writes more units than its declared finish bound.