pub struct AsyncTranscodeDecodeInput<I>{ /* private fields */ }Expand description
Decodes an asynchronous unit stream into values.
The adapter owns unit buffering but not decoder state. Callers supply a streaming decoder and error mapper for each operation.
§Driving input through EOF
Reset the decoder first and collect the number of values it writes. For
each Self::poll_transcode progress result, add written() to the output
cursor; the bridge has already consumed read() from its unread buffer.
When the status is NeedInput { required }, call
Self::fill_until_async with required.get(). If it returns true, poll
the decoder again. If it returns false, EOF has been confirmed and any
short tail remains unread; pass that tail to Self::transcode_eof_step.
Keep stepping on NeedOutput with a sufficiently large output range. Once
EOF processing returns Complete, call Self::finish and collect its
returned output count. EndOfInput from polling means the unread buffer was
already empty when refill confirmed EOF. In both cases, call
Self::transcode_eof_step to dispatch the EOF event, including when no
unread units remain.
§Type Parameters
I: Wrapped asynchronous unit input.
§Examples
use qubit_codec::AsyncTranscodeDecodeInput;
use qubit_io::AsyncInput;
let mut input = AsyncTranscodeDecodeInput::with_capacity(EmptyInput, 8);
assert!(input.capacity() >= 8);
assert_eq!(input.unread_len(), 0);
input.consume(0);
assert!(input.unread().is_empty());The following driver decodes one complete pair, preserves a one-unit tail,
retries EOF processing after NeedOutput, and collects lifecycle output
without an async runtime. The source and decoder are small fixtures; real
applications use their own AsyncInput and Transcoder implementations.
use qubit_codec::{AsyncTranscodeDecodeInput, AsyncTranscodeDecodeStep, CapacityError, TranscodeDecodeError, TranscodeProgress, Transcoder};
use qubit_io::AsyncInput;
use std::convert::Infallible;
use std::future::{poll_fn, Future};
use std::io;
use std::num::NonZeroUsize;
use std::pin::{pin, Pin};
use std::task::{Context, Poll, Waker};
let source = ThreeBytes { bytes: [0x12, 0x34, 0x56], position: 0 };
let mut input = AsyncTranscodeDecodeInput::with_capacity(source, 2);
let mut decoder = TailDecoder;
let mut output = [0_u16; 4];
let output_len = output.len();
let mut map_error = |error| io::Error::new(io::ErrorKind::InvalidData, error);
let mut written = input.reset(&mut decoder, &mut map_error, &mut output, 0, output_len)?;
assert_eq!(1, written);
let first = block_on(poll_fn(|cx| Pin::new(&mut input).poll_transcode(cx, &mut decoder, &mut map_error, &mut output, written, output_len - written)))?;
let AsyncTranscodeDecodeStep::Progress(progress) = first else { panic!("expected decoded pair") };
assert_eq!(TranscodeProgress::complete(2, 1), progress);
written += progress.written();
assert_eq!(0x1234, output[1]);
let second = block_on(poll_fn(|cx| Pin::new(&mut input).poll_transcode(cx, &mut decoder, &mut map_error, &mut output, written, output_len - written)))?;
assert!(matches!(second, AsyncTranscodeDecodeStep::Progress(progress) if matches!(progress.status(), qubit_codec::TranscodeStatus::NeedInput { .. })));
assert!(!block_on(input.fill_until_async(2))?);
assert_eq!([0x56], input.unread());
let eof = input.transcode_eof_step(&mut decoder, &mut map_error, &mut output, written, 1)?;
assert_eq!(TranscodeProgress::need_output(NonZeroUsize::new(2).unwrap(), 0, 0), eof);
let eof = input.transcode_eof_step(&mut decoder, &mut map_error, &mut output, written, 2)?;
assert_eq!(TranscodeProgress::complete(1, 1), eof);
written += eof.written();
let finished = input.finish(&mut decoder, &mut map_error, &mut output, written, output_len - written)?;
written += finished;
assert_eq!([0xaaaa, 0x1234, 0x56, 0xbbbb], output);
assert_eq!(4, written);Implementations§
Source§impl<I> AsyncTranscodeDecodeInput<I>
impl<I> AsyncTranscodeDecodeInput<I>
Sourcepub fn with_capacity(inner: I, capacity: usize) -> Self
pub fn with_capacity(inner: I, capacity: usize) -> Self
Sourcepub fn try_with_capacity(
inner: I,
capacity: usize,
) -> Result<Self, TryReserveError>
pub fn try_with_capacity( inner: I, capacity: usize, ) -> Result<Self, TryReserveError>
Tries to create an adapter with an internal unit buffer of at least capacity.
§Parameters
inner: Asynchronous unit source owned by the adapter.capacity: Minimum requested unit-buffer capacity.
§Returns
The adapter with an empty unread window on successful allocation.
§Errors
Returns the allocation error when the internal buffer cannot be allocated.
Sourcepub const fn inner(&self) -> &I
pub const fn inner(&self) -> &I
Returns a shared reference to the wrapped asynchronous input.
The input can be physically positioned after units retained in this adapter’s unread buffer.
§Returns
A shared borrow of the underlying source, excluding buffered units.
Sourcepub fn inner_mut(&mut self) -> &mut I
pub fn inner_mut(&mut self) -> &mut I
Returns a mutable reference to the wrapped asynchronous input.
Direct reads can invalidate the logical stream position represented by unread buffered units.
§Returns
An exclusive borrow of the source; direct reads bypass buffered units.
Sourcepub const fn unread_len(&self) -> usize
pub const fn unread_len(&self) -> usize
Returns the number of unread units currently buffered.
§Returns
The number of buffered units not yet consumed.
Sourcepub fn unread(&self) -> &[I::Item]
pub fn unread(&self) -> &[I::Item]
Returns the unread buffered unit window.
§Returns
The currently retained units borrowed without allocation.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the total internal unit-buffer capacity.
§Returns
The total number of units the internal buffer can hold.
Sourcepub unsafe fn copy_unread_to(
&self,
output: &mut [I::Item],
output_index: usize,
count: usize,
)
pub unsafe fn copy_unread_to( &self, output: &mut [I::Item], output_index: usize, count: usize, )
Copies unread units into an indexed output range without consuming them.
§Parameters
output: Destination slice receiving copies of retained units.output_index: First destination index.count: Number of unread units to copy without consuming them.
§Safety
The caller must guarantee that the indexed range fits in output, does not overflow, holds no overlapping unread units, and count is no greater than the unread unit count.
Sourcepub fn into_parts(self) -> (I, Buffer<I::Item>)
pub fn into_parts(self) -> (I, Buffer<I::Item>)
Consumes this adapter and returns the input plus its unread buffer.
§Returns
The owned source and buffer, preserving all unread units.
Sourcepub fn reset<D, M, Value>(
&self,
decoder: &mut D,
map_error: &mut M,
output: &mut [Value],
output_index: usize,
count: usize,
) -> Result<usize>
pub fn reset<D, M, Value>( &self, decoder: &mut D, map_error: &mut M, output: &mut [Value], output_index: usize, count: usize, ) -> Result<usize>
Runs decoder reset into an indexed output range without I/O.
§Type Parameters
D: Stateful decoder from source units into values.M: Callback mapping decoder errors to I/O errors.Value: Destination value type.
§Parameters
decoder: Decoder whose state may change during this operation.map_error: Callback invoked for decoder errors.output: Destination value slice.output_index: First destination index.count: Number of writable destination positions.
§Returns
Number of values emitted during decoder reset.
§Errors
Returns invalid output-range, capacity, or mapped decoder-reset errors.
§Panics
Panics if the decoder writes more values than its reset bound.
Sourcepub fn finish<D, M, Value>(
&self,
decoder: &mut D,
map_error: &mut M,
output: &mut [Value],
output_index: usize,
count: usize,
) -> Result<usize>
pub fn finish<D, M, Value>( &self, decoder: &mut D, map_error: &mut M, output: &mut [Value], output_index: usize, count: usize, ) -> Result<usize>
Finishes a decoder into an indexed output range without I/O.
§Type Parameters
D: Stateful decoder from source units into values.M: Callback mapping decoder errors to I/O errors.Value: Destination value type.
§Parameters
decoder: Decoder whose state may change during this operation.map_error: Callback invoked for decoder errors.output: Destination value slice.output_index: First destination index.count: Number of writable destination positions.
§Returns
Number of values emitted while finishing the decoder.
§Errors
Returns invalid output-range, capacity, or mapped decoder-finish errors.
§Panics
Panics if the decoder writes more values than its finish bound.
Source§impl<I> AsyncTranscodeDecodeInput<I>
impl<I> AsyncTranscodeDecodeInput<I>
Sourcepub async fn fill_more_async(&mut self) -> Result<bool>
pub async fn fill_more_async(&mut self) -> Result<bool>
Sourcepub async fn fill_until_async(&mut self, count: usize) -> Result<bool>
pub async fn fill_until_async(&mut self, count: usize) -> Result<bool>
Refills until at least count unread units are available.
§Parameters
count: Minimum desired unread unit count; grows the buffer if needed.
§Returns
Returns true when count units are available, or false when EOF occurs first.
§Errors
Returns allocation, input, or buffer-management errors while refilling.
Sourcepub fn poll_transcode<D, M, Value>(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
decoder: &mut D,
map_error: &mut M,
output: &mut [Value],
output_index: usize,
count: usize,
) -> Poll<Result<AsyncTranscodeDecodeStep>>
pub fn poll_transcode<D, M, Value>( self: Pin<&mut Self>, cx: &mut Context<'_>, decoder: &mut D, map_error: &mut M, output: &mut [Value], output_index: usize, count: usize, ) -> Poll<Result<AsyncTranscodeDecodeStep>>
Polls one cancellation-safe decoder operation.
The operation first refills only when no unread unit is buffered. After
a decoder call changes either the decoder or the buffered input, it
immediately returns AsyncTranscodeDecodeStep::Progress and never
polls the input again. This makes the returned progress the commit
boundary for cancellation: resume with the adapter’s current state,
rather than replaying the previous source range.
§Type Parameters
D: Stateful decoder from source units into values.M: Callback mapping decoder errors to I/O errors.Value: Destination value type.
§Parameters
cx: Task context used when polling the source.decoder: Decoder whose state may change during this operation.map_error: Callback invoked for decoder errors.output: Destination value slice.output_index: First destination index.count: Number of writable destination positions.
§Returns
Pending only while awaiting source input before decoding; otherwise
ready progress or end-of-input. Successful progress has already
consumed source units.
§Errors
Returns input, allocation, output-range, invalid-progress, or mapped decoder errors.
Sourcepub fn transcode_eof_step<D, M, Value>(
&mut self,
decoder: &mut D,
map_error: &mut M,
output: &mut [Value],
output_index: usize,
count: usize,
) -> Result<TranscodeProgress>
pub fn transcode_eof_step<D, M, Value>( &mut self, decoder: &mut D, map_error: &mut M, output: &mut [Value], output_index: usize, count: usize, ) -> Result<TranscodeProgress>
Performs one decode step after the caller has established EOF.
This method performs no I/O. It passes the current unread buffer to
Transcoder::transcode_eof, validates progress, and commits consumed
source units before returning.
§Type Parameters
D: Stateful decoder from source units into values.M: Callback mapping decoder errors to I/O errors.Value: Destination value type.
§Parameters
decoder: Decoder whose state may change during this operation.map_error: Callback invoked for decoder errors.output: Destination value slice.output_index: First destination index.count: Number of writable destination positions.
§Returns
Validated progress with source consumption committed. A zero output
count returns zero progress without calling the decoder; an empty input
is still dispatched to transcode_eof.
§Errors
Returns invalid output-range errors, or decoder errors mapped by
map_error, and invalid-progress errors from contract validation.
Sourcepub async fn transcode_async<D, M, Value>(
&mut self,
decoder: &mut D,
map_error: &mut M,
output: &mut [Value],
output_index: usize,
count: usize,
) -> Result<AsyncTranscodeDecodeStep>
pub async fn transcode_async<D, M, Value>( &mut self, decoder: &mut D, map_error: &mut M, output: &mut [Value], output_index: usize, count: usize, ) -> Result<AsyncTranscodeDecodeStep>
Decodes one cancellation-safe progress step into an indexed output range.
This is the async wrapper for Self::poll_transcode. It returns after
one decoder invocation; callers that require a complete destination
range must drive successive steps and retain each returned progress.
§Type Parameters
D: Stateful decoder from source units into values.M: Callback mapping decoder errors to I/O errors.Value: Destination value type.
§Parameters
decoder: Decoder whose state may change during this operation.map_error: Callback invoked for decoder errors.output: Destination value slice.output_index: First destination index.count: Number of writable destination positions.
§Returns
One committed progress step, or end-of-input when the source is exhausted.
§Errors
Returns input, allocation, output-range, invalid-progress, or mapped
decoder errors from poll_transcode.
Trait Implementations§
Source§impl<I> AsyncInput for AsyncTranscodeDecodeInput<I>
impl<I> AsyncInput for AsyncTranscodeDecodeInput<I>
Source§type Item = <I as AsyncInput>::Item
type Item = <I as AsyncInput>::Item
Item type read through the retained unit buffer.
Source§fn is_buffered(&self) -> bool
fn is_buffered(&self) -> bool
Reports that this input retains unread units.
§Returns
Always true, because this adapter retains unread units.
Source§unsafe fn poll_read_unchecked(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
output: &mut [Self::Item],
index: usize,
count: usize,
) -> Poll<Result<usize>>
unsafe fn poll_read_unchecked( self: Pin<&mut Self>, cx: &mut Context<'_>, output: &mut [Self::Item], index: usize, count: usize, ) -> Poll<Result<usize>>
Polls one read through the retained unit buffer.
§Parameters
cx: Task context used to poll the buffered source.output: Destination unit slice.index: First destination index.count: Maximum number of units to read.
§Returns
Pending while awaiting source data, or a ready read count; zero
indicates EOF.
§Errors
Returns errors from the buffered source or its buffer management.
§Safety
The caller must provide a valid indexed output range.