pub struct TranscodeEncodeOutput<O>{ /* private fields */ }Expand description
Encodes an Output value stream into an Output unit stream.
This type owns only the unit-level qubit_io::BufferedOutput. Callers
pass a crate::Codec and error mapper to each encode operation, which
lets one buffered output drive different encoders without nesting buffers or
storing codec-specific state in the buffer owner.
Self::flush only drains already buffered units. State-aware streaming
encoders can use Self::reset, Self::transcode, and Self::finish
explicitly.
Pending units should be flushed or recovered before this adapter is dropped. Its wrapped buffer only makes a best-effort drain during drop, skips that drain after an inner I/O panic, and ignores any output error.
§Type Parameters
O- Wrapped unit output.
§Examples
use core::convert::Infallible;
use core::num::NonZeroUsize;
use std::io::Cursor;
use qubit_codec::{Codec, CodecTranscodeEncoder, DecodeFailure, TranscodeEncodeOutput};
use qubit_codec::{TranscodeEncoder, TranscodeStatus};
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)
-> Result<(u8, NonZeroUsize), DecodeFailure<Infallible>> {
Ok((input[index], NonZeroUsize::MIN))
}
unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
-> Result<usize, Infallible> {
output[index] = *value;
Ok(1)
}
}
let mut encoder = CodecTranscodeEncoder::new(ByteCodec);
let mut output = TranscodeEncodeOutput::with_capacity(Cursor::new(Vec::new()), 8);
let mut map_error = |_| std::io::Error::other("encode error");
output.reset(&mut encoder, &mut map_error)?;
let values = [1_u8, 2, 3];
let mut offset = 0;
while offset < values.len() {
let progress = output.transcode_step(
&mut encoder, &mut map_error, &values, offset, values.len() - offset,
)?;
offset += progress.read();
if let TranscodeStatus::NeedOutput { required, .. } = progress.status() {
output.ensure_spare_capacity(required.get())?;
}
}
output.finish(&mut encoder, &mut map_error)?;
assert_eq!(output.inner().get_ref(), &[1, 2, 3]);finish commits final units, drains the buffered output, and flushes the
wrapped sink. Use finish_to_buffer followed by flush when those steps
need to be controlled separately.
Implementations§
Source§impl<O> TranscodeEncodeOutput<O>
impl<O> TranscodeEncodeOutput<O>
Sourcepub fn new(inner: O) -> Self
pub fn new(inner: O) -> Self
Creates an encoder output with the default unit buffer capacity.
§Parameters
inner- Unit output written by this adapter.
§Returns
A new buffered encoder output.
§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 encoder output with a unit buffer of at least capacity.
§Parameters
inner- Unit output written by this adapter.capacity- Requested internal unit buffer capacity.
§Returns
A new buffered encoder output.
§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,
) -> CoreResult<Self, TryReserveError>
pub fn try_with_capacity( inner: O, capacity: usize, ) -> CoreResult<Self, TryReserveError>
Creates an encoder output with a unit buffer of at least capacity.
§Parameters
inner- Unit output written by this adapter.capacity- Requested internal unit buffer capacity.
§Returns
A buffered adapter owning inner on success.
§Errors
Returns an allocation error when the requested buffer cannot be allocated.
§Panics
Panics if initializing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics. Allocation failures are
returned as errors; panics from element initialization are not caught.
Sourcepub const fn inner(&self) -> &O
pub const fn inner(&self) -> &O
Returns a shared reference to the wrapped unit output.
Pending units remain in this adapter’s internal buffer and are not
visible through the returned output until Self::flush succeeds.
§Returns
A shared reference to the wrapped unit output.
Sourcepub fn spare_capacity(&self) -> usize
pub fn spare_capacity(&self) -> usize
Returns the available capacity of the spare output buffer.
§Returns
The number of output units that can still be appended without flushing.
Sourcepub fn spare_raw_parts_mut(&mut self) -> (&mut [O::Item], usize, usize)
pub fn spare_raw_parts_mut(&mut self) -> (&mut [O::Item], usize, usize)
Returns raw spare-buffer parts for the internal output buffer.
§Returns
The full backing storage, the spare start index, and the spare unit count.
Sourcepub unsafe fn advance(&mut self, count: usize)
pub unsafe fn advance(&mut self, count: usize)
Marks count units from Self::spare_raw_parts_mut as written.
§Parameters
count- Initialized units to commit from the spare window.
§Safety
The caller must guarantee that count <= Self::spare_capacity() and
that the corresponding units in the returned spare slice have been
initialized.
Sourcepub fn ensure_spare_capacity(&mut self, count: usize) -> Result<()>
pub fn ensure_spare_capacity(&mut self, count: usize) -> Result<()>
Ensures that at least count spare units are available.
§Parameters
count- Number of spare units required.
§Errors
Returns allocation errors mapped to ErrorKind::OutOfMemory, or I/O
errors from the wrapped output while delivering pending units.
§Panics
Panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
Sourcepub fn into_parts(self) -> (O, BufferedOutputRecovery<O::Item>)
pub fn into_parts(self) -> (O, BufferedOutputRecovery<O::Item>)
Consumes this adapter without flushing the wrapped output.
This method does not call Self::flush and performs no I/O. Pending
units were not reported as written and may be retried. Indeterminate
means an inner write panicked and may have produced an external prefix;
do not replay it automatically.
§Returns
The wrapped output and pending or indeterminate units.
Sourcepub fn flush(&mut self) -> Result<()>
pub fn flush(&mut self) -> Result<()>
Flushes buffered units without finishing any encoder stream.
§Errors
Returns errors from the wrapped output while flushing pending units.
Sourcepub fn write_encoded_with<C, M>(
&mut self,
codec: &mut C,
value: &C::Value,
map_error: M,
) -> Result<()>
pub fn write_encoded_with<C, M>( &mut self, codec: &mut C, value: &C::Value, map_error: M, ) -> Result<()>
Encodes one codec value into this buffered unit output.
The method grows the persistent internal buffer when necessary, then writes the complete encoded value into its spare window.
§Type Parameters
C- Codec producing the wrapped output unit type.M- Mapper from codec errors into I/O errors.
§Parameters
codec- Codec used for this single-value encode.value- Value to encode.map_error- Mapper for codec-domain encode errors.
§Errors
Returns I/O errors from the wrapped output, InvalidInput when the
codec output bound overflows or the value is outside the codec domain,
or the error returned by map_error for codec encode, reset, and finish
failures. A mapped codec error is wrapped in
crate::TranscodeDomainError so its reset, main, or finish phase
remains available through the returned I/O error’s source chain. The
mapped error itself is retained as that wrapper’s source, including any
custom payload or OS error code.
Capacity planning fails before the codec runs. Preparing the spare buffer can first deliver older pending units to the wrapped output; it is not a transaction boundary for the whole call. If reset, encode, or finish fails, the codec may already have changed state, but units written into this call’s spare window are not committed to the adapter. Older pending units remain subject to the wrapped output’s buffering contract, and units delivered while preparing capacity cannot be rolled back. A successful call commits the actual written count to pending output but does not flush the sink. Do not replay the value after an error unless the codec provides a recovery protocol; reset does not undo state changes or output already delivered.
Callers that previously downcast the outer I/O error directly to their
mapped payload should first downcast it to
TranscodeDomainError<std::io::Error>, then inspect its source().
For mapped OS errors, raw_os_error() is available on that inner
source.
§Panics
Panics when the codec violates its declared reset, value-width, or
finish bounds, or when encode writes a length different from
encode_len in the same reset state. Also panics if growing the buffer
requires O::Item::default() or O::Item::clone() and either
operation panics.
Sourcepub fn reset<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
) -> Result<()>
pub fn reset<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, ) -> Result<()>
Runs encoder reset and buffers any stream-prefix units.
This method reserves enough persistent buffer capacity for all reset
output before calling encoder. Preparing that space may deliver
previously buffered units to the wrapped output and can return an I/O
error before encoder.reset runs. This delivery does not call the
wrapped output’s flush method.
§Type Parameters
E- Transcoder producing the wrapped output unit type.M- Mapper from transcoder errors into I/O errors.Value- Source value type accepted by the transcoder.
§Parameters
encoder- Transcoder whose stream prefix is being collected.map_error- Mapper for reset failures.
§Errors
Returns capacity errors, allocation errors, or reset errors mapped by
map_error.
§Panics
Panics when encoder writes more than its declared reset bound.
Also panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
Sourcepub fn transcode_step<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
input: &[Value],
input_index: usize,
count: usize,
) -> Result<TranscodeProgress>
pub fn transcode_step<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, input: &[Value], input_index: usize, count: usize, ) -> Result<TranscodeProgress>
Encodes at most one step of the selected input range.
Unlike Self::transcode, this method does not reserve output space
for the entire range and calls the encoder exactly once. The returned
progress is relative to this call’s input and output windows. Advance
the input index by TranscodeProgress::read; if the status is
NeedOutput, provide the requested spare capacity before retrying.
Written units have already been committed to this adapter’s pending
buffer and must not be advanced again. A zero count validates the range
and returns complete progress without delivering pending units or
calling the encoder.
§Type Parameters
E- Encoder producing the wrapped output unit type.M- Mapper from encoder errors into I/O errors.Value- Source value type accepted by the encoder.
§Parameters
encoder- Encoder that processes one progress step.map_error- Maps encoder errors to I/O errors.input- Source values.input_index- Start index insideinput.count- Number of values available frominput_index.
§Returns
Progress for the single encoder call, including consumed input, committed output, and whether more output capacity is needed.
§Errors
Returns invalid input ranges, capacity, encoder, or output errors. An
invalid encoder progress report is returned as ErrorKind::InvalidData.
An 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 without an encoder-specific
recovery protocol. Earlier pending units retain the wrapped output’s
recovery contract; reset starts a new logical stream and does not undo
output already delivered.
§Panics
Panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
§Examples
use std::io::Cursor;
use qubit_codec::TranscodeEncodeOutput;
use qubit_codec::TranscodeEncoder;
use qubit_codec::TranscodeStatus;
fn encode<E>(encoder: &mut E, values: &[E::Input]) -> std::io::Result<Vec<u8>>
where
E: TranscodeEncoder<Output = u8>,
{
let mut output = TranscodeEncodeOutput::with_capacity(Cursor::new(Vec::new()), 8);
let mut map_error = |_| std::io::Error::other("encode error");
output.reset(encoder, &mut map_error)?;
let mut offset = 0;
while offset < values.len() {
let progress = output.transcode_step(
encoder,
&mut map_error,
values,
offset,
values.len() - offset,
)?;
offset += progress.read();
if let TranscodeStatus::NeedOutput { required, .. } = progress.status() {
output.ensure_spare_capacity(required.get())?;
}
}
output.finish(encoder, &mut map_error)?;
let (cursor, _) = output.into_parts();
Ok(cursor.into_inner())
}
let mut encoder = CodecTranscodeEncoder::new(ByteCodec);
assert_eq!(encode(&mut encoder, &[1, 2, 3]).unwrap(), vec![1, 2, 3]);
let mut empty_encoder = CodecTranscodeEncoder::new(ByteCodec);
assert_eq!(encode(&mut empty_encoder, &[]).unwrap(), Vec::<u8>::new());Sourcepub fn transcode<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
input: &[Value],
input_index: usize,
count: usize,
) -> Result<usize>
pub fn transcode<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, input: &[Value], input_index: usize, count: usize, ) -> Result<usize>
Encodes values from an indexed input range using a streaming
Transcoder.
This streaming path reserves the encoder’s conservative output bound for the whole batch before calling it. Preparing that space may deliver previously buffered units to the wrapped output and can return an I/O error before consuming source values. Split large batches into smaller calls when you need to limit the memory required for one operation.
§Type Parameters
E- Encoder producing the wrapped output unit type.M- Mapper from encoder errors into I/O errors.Value- Source value type accepted by the encoder.
§Parameters
encoder- Streaming encoder used for this operation.map_error- Function mapping transcode errors into I/O errors.input- Source values.input_index- Start index insideinput.count- Maximum number of values to encode.
§Returns
The number of source values consumed.
§Errors
Returns invalid input ranges, capacity, transcode, or output errors. An
output-bound contract violation is reported as ErrorKind::InvalidData.
An error does not provide general transactional rollback or complete
progress. The encoder may already have advanced, while 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
output remains subject to the wrapped output’s recovery contract, and
reset starts a new logical stream without undoing output already
delivered.
§Panics
Panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
§Examples
A value that only implements Transcoder is not an encoder and cannot
be passed to this method.
use std::io::Error;
use std::io::sink;
use qubit_codec::CapacityError;
use qubit_codec::TranscodeEncodeError;
use qubit_codec::TranscodeEncodeOutput;
use qubit_codec::TranscodeProgress;
use qubit_codec::Transcoder;
struct GenericTranscoder;
impl Transcoder for GenericTranscoder {
type Input = u8;
type Output = u8;
type Error = TranscodeEncodeError<(), u8>;
fn max_transcode_output_len(
&self,
input_len: usize,
) -> Result<usize, CapacityError> {
Ok(input_len)
}
fn reset(
&mut self,
_output: &mut [u8],
_output_index: usize,
) -> Result<usize, Self::Error> {
Ok(0)
}
fn transcode(
&mut self,
input: &[u8],
input_index: usize,
_output: &mut [u8],
_output_index: usize,
) -> Result<TranscodeProgress, Self::Error> {
Ok(TranscodeProgress::complete(input.len() - input_index, 0))
}
fn finish(
&mut self,
_output: &mut [u8],
_output_index: usize,
) -> Result<usize, Self::Error> {
Ok(0)
}
}
let mut output = TranscodeEncodeOutput::with_capacity(sink(), 1);
let mut transcoder = GenericTranscoder;
let mut map_error = |_| Error::other("transcode error");
let _ = output.transcode(
&mut transcoder,
&mut map_error,
&[0_u8],
0,
1,
);Sourcepub fn finish<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
) -> Result<()>
pub fn finish<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, ) -> Result<()>
Finishes the encoder and flushes the wrapped unit output.
This method writes final units directly into the internal spare buffer,
growing it when Transcoder::max_finish_output_len exceeds the
current capacity.
§Type Parameters
E- Transcoder producing the wrapped output unit type.M- Mapper from transcoder errors into I/O errors.Value- Source value type accepted by the transcoder.
§Parameters
encoder- Encoder whose final units are being collected.map_error- Function mapping transcode errors into I/O errors.
§Errors
Returns capacity, transcode finalization, or wrapped output flush errors.
§Panics
Panics when the encoder exceeds its declared finish-output bound.
Also panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
Sourcepub fn finish_to_buffer<E, M, Value>(
&mut self,
encoder: &mut E,
map_error: &mut M,
) -> Result<()>
pub fn finish_to_buffer<E, M, Value>( &mut self, encoder: &mut E, map_error: &mut M, ) -> Result<()>
Finishes the encoder while retaining final units in the output buffer.
This method separates encoder finalization from output delivery. It is
useful when a caller must record successful finalization before a later
flush can fail. Call Self::flush to deliver the retained units.
§Type Parameters
E- Transcoder producing the wrapped output unit type.M- Mapper from transcoder errors into I/O errors.Value- Source value type accepted by the transcoder.
§Parameters
encoder- Encoder whose final units are being collected.map_error- Function mapping transcode errors into I/O errors.
§Errors
Returns capacity planning, allocation, or transcoder finalization
errors. It does not perform output I/O; use Self::finish to deliver
the buffered final units and flush the wrapped output.
§Panics
Panics when encoder writes more units than its declared finish bound.
Also panics if growing the buffer requires O::Item::default() or
O::Item::clone() and either operation panics.
Source§impl<O> TranscodeEncodeOutput<O>where
O: SeekableByteOutput,
impl<O> TranscodeEncodeOutput<O>where
O: SeekableByteOutput,
Trait Implementations§
Source§impl<O> Debug for TranscodeEncodeOutput<O>
impl<O> Debug for TranscodeEncodeOutput<O>
Source§impl<O> Seek for TranscodeEncodeOutput<O>where
O: SeekableByteOutput,
impl<O> Seek for TranscodeEncodeOutput<O>where
O: SeekableByteOutput,
1.55.0 · Source§fn rewind(&mut self) -> Result<(), Error>
fn rewind(&mut self) -> Result<(), Error>
Source§fn stream_len(&mut self) -> Result<u64, Error>
fn stream_len(&mut self) -> Result<u64, Error>
seek_stream_len)Source§impl<O> Write for TranscodeEncodeOutput<O>where
O: ByteOutput,
impl<O> Write for TranscodeEncodeOutput<O>where
O: ByteOutput,
Source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Flushes buffered bytes to the wrapped output without finishing an encoder.
§Errors
Propagates wrapped-output flush errors.
Source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector)Source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored)Auto Trait Implementations§
impl<O> Freeze for TranscodeEncodeOutput<O>
impl<O> RefUnwindSafe for TranscodeEncodeOutput<O>
impl<O> Send for TranscodeEncodeOutput<O>
impl<O> Sync for TranscodeEncodeOutput<O>
impl<O> Unpin for TranscodeEncodeOutput<O>
impl<O> UnsafeUnpin for TranscodeEncodeOutput<O>
impl<O> UnwindSafe for TranscodeEncodeOutput<O>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> ByteOutput for T
Source§impl<W> Output for W
impl<W> Output for W
Source§unsafe fn write_unchecked(
&mut self,
input: &[u8],
index: usize,
count: usize,
) -> Result<usize, Error>
unsafe fn write_unchecked( &mut self, input: &[u8], index: usize, count: usize, ) -> Result<usize, Error>
Writes bytes from a caller-validated indexed input range.
§Parameters
input: Source byte slice.index: Start offset insideinput.count: Maximum number of bytes to write.
§Returns
The number of bytes reported by the standard writer.
§Errors
Returns the error reported by the standard writer.
§Panics
Panics in debug builds if the requested source range does not fit.
§Safety
The caller must ensure that index through index plus count is a valid range inside input without overflowing.
Source§fn write(&mut self, input: &[<W as Output>::Item]) -> Result<usize, Error>
fn write(&mut self, input: &[<W as Output>::Item]) -> Result<usize, Error>
Writes bytes from the complete input slice.
§Parameters
input: Source byte slice.
§Returns
The number of bytes written from input.
§Errors
Returns std::io::ErrorKind::InvalidData if the writer reports more
bytes than input contains, or the error reported by the standard
writer.
Source§fn write_vectored(&mut self, buffers: &[&[u8]]) -> Result<usize, Error>
fn write_vectored(&mut self, buffers: &[&[u8]]) -> Result<usize, Error>
Writes from the buffers in order using the standard writer’s vectored method. A single descriptor uses stack storage; multiple descriptors may allocate descriptor storage, and the writer may allocate independently. Short progress and writer errors are returned without retrying or undoing underlying side effects.
§Parameters
buffers: Ordered source byte slices.
§Returns
The number of bytes reported by the standard writer, up to the total buffer length. Returns zero without calling the writer when all buffers are empty.
§Errors
Returns std::io::ErrorKind::InvalidInput if the total buffer length
overflows, std::io::ErrorKind::OutOfMemory if multiple-descriptor
preparation fails before I/O, std::io::ErrorKind::InvalidData if
the writer reports more than the total buffer length, or the error
returned by the standard writer.
Source§fn into_std_write(self) -> StdWrite<Self> ⓘwhere
Self: Sized + ByteOutput,
fn into_std_write(self) -> StdWrite<Self> ⓘwhere
Self: Sized + ByteOutput,
Source§fn is_buffered(&self) -> bool
fn is_buffered(&self) -> bool
impl<T> SeekableByteOutput for T
impl<T> SeekableOutput for T
Source§impl<T> WriteExt for T
impl<T> WriteExt for T
impl<T> WriteSeek for T
Source§impl<T> WriteSeekExt for T
impl<T> WriteSeekExt for T
Source§fn write_all_at_preserving_position(
&mut self,
offset: u64,
buffer: &[u8],
) -> Result<(), Error>
fn write_all_at_preserving_position( &mut self, offset: u64, buffer: &[u8], ) -> Result<(), Error>
Writes at an absolute offset and restores the original position.
§Parameters
offset: Absolute byte offset to write at.buffer: Bytes to write.
§Returns
Ok(()) after all bytes have been written and the position restored.
§Errors
Returns an error when querying, changing, or restoring the stream position, or when writing fails.