qubit_codec/transcode/io/transcode_decode_input.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//! Buffered input driver that decodes units into values.
9
10use core::fmt;
11use std::collections::TryReserveError;
12use std::io::{
13 Error,
14 ErrorKind,
15 Read,
16 Result,
17 Seek,
18 SeekFrom,
19};
20
21use qubit_io::{
22 Buffer,
23 BufferedInput,
24 Input,
25 Seekable,
26 UncheckedSlice,
27};
28
29use crate::{
30 Codec,
31 DecodeLifecycleOutput,
32 DecodeLifecycleProgress,
33 TranscodeFailure,
34 TranscodeProgress,
35 TranscodeStatus,
36 Transcoder,
37 codec::assert_unit_bounds,
38};
39
40use super::codec_decode_driver::CodecDecodeDriver;
41use super::transcode_progress_validation::validate_decode_progress;
42
43/// Decodes an [`Input`] unit stream into an [`Input`] value stream.
44///
45/// This type owns only the unit-level [`qubit_io::BufferedInput`]. Callers pass
46/// a streaming [`Transcoder`] and error mapper to each decode operation, which
47/// lets one buffered input drive different decoders without nesting buffers or
48/// storing decoder-specific state in the buffer owner.
49///
50/// # Type Parameters
51///
52/// * `I` - Wrapped unit input.
53pub struct TranscodeDecodeInput<I>
54where
55 I: Input,
56 I::Item: Copy + Default,
57{
58 input: BufferedInput<I>,
59}
60
61impl<I> TranscodeDecodeInput<I>
62where
63 I: Input,
64 I::Item: Copy + Default,
65{
66 /// Creates a decoder input with the default unit buffer capacity.
67 ///
68 /// # Parameters
69 ///
70 /// * `inner` - Unit input read by this adapter.
71 ///
72 /// # Returns
73 ///
74 /// A new buffered decoder input.
75 #[must_use]
76 pub fn new(inner: I) -> Self {
77 Self {
78 input: BufferedInput::new(inner),
79 }
80 }
81
82 /// Creates a decoder input with a unit buffer of at least `capacity`.
83 ///
84 /// # Parameters
85 ///
86 /// * `inner` - Unit input read by this adapter.
87 /// * `capacity` - Requested internal unit buffer capacity.
88 ///
89 /// # Returns
90 ///
91 /// A new buffered decoder input.
92 #[must_use]
93 pub fn with_capacity(inner: I, capacity: usize) -> Self {
94 Self {
95 input: BufferedInput::with_capacity(inner, capacity),
96 }
97 }
98
99 /// Creates a decoder input with a unit buffer of at least `capacity`.
100 ///
101 /// # Parameters
102 ///
103 /// * `inner` - Unit input read by this adapter.
104 /// * `capacity` - Requested internal unit buffer capacity.
105 ///
106 /// # Errors
107 ///
108 /// Returns an allocation error when the requested buffer cannot be
109 /// allocated.
110 #[inline]
111 pub fn try_with_capacity(
112 inner: I,
113 capacity: usize,
114 ) -> std::result::Result<Self, TryReserveError> {
115 Ok(Self {
116 input: BufferedInput::try_with_capacity(inner, capacity)?,
117 })
118 }
119
120 /// Returns a shared reference to the wrapped unit input.
121 ///
122 /// The wrapped input can be physically positioned after units that remain
123 /// unread in this adapter's internal buffer.
124 ///
125 /// # Returns
126 ///
127 /// A shared reference to the wrapped unit input.
128 #[must_use]
129 pub const fn inner(&self) -> &I {
130 self.input.inner()
131 }
132
133 /// Returns the number of unread units currently buffered.
134 ///
135 /// # Returns
136 ///
137 /// The number of unread units in the internal buffer.
138 #[must_use]
139 pub fn unread_len(&self) -> usize {
140 self.input.unread_len()
141 }
142
143 /// Returns the currently buffered unread units.
144 ///
145 /// # Returns
146 ///
147 /// Returns a shared slice over the unread portion of the internal unit
148 /// buffer. The slice is valid until this adapter is mutated.
149 #[must_use]
150 pub fn unread(&self) -> &[I::Item] {
151 self.input.unread()
152 }
153
154 /// Returns the internal unit buffer capacity.
155 ///
156 /// # Returns
157 ///
158 /// The maximum number of units retained in the internal buffer.
159 #[must_use]
160 pub fn capacity(&self) -> usize {
161 self.input.capacity()
162 }
163
164 /// Refills the internal buffer until at least `count` unread units are
165 /// available.
166 ///
167 /// # Parameters
168 ///
169 /// * `count` - Minimum number of unread units required.
170 ///
171 /// # Errors
172 ///
173 /// Returns allocation errors mapped to [`ErrorKind::OutOfMemory`], or I/O
174 /// errors from the wrapped input while refilling.
175 pub fn fill_until(&mut self, count: usize) -> std::io::Result<bool> {
176 if count > self.input.capacity() {
177 self.input
178 .try_reserve_capacity(count)
179 .map_err(allocation_to_io_error)?;
180 }
181 self.input.fill_until(count)
182 }
183
184 /// Performs one decode step and preserves the transcoder stop status.
185 ///
186 /// `None` means that the wrapped input reached EOF with no buffered units.
187 /// Consumed input is committed before this method returns. Callers can use
188 /// the returned [`TranscodeProgress`] to distinguish `NeedOutput` from an
189 /// incomplete input tail without guessing from the unread buffer alone.
190 pub fn transcode_step<D, M, Value>(
191 &mut self,
192 decoder: &mut D,
193 map_error: &mut M,
194 output: &mut [Value],
195 output_index: usize,
196 count: usize,
197 ) -> Result<Option<TranscodeProgress>>
198 where
199 D: Transcoder<Input = I::Item, Output = Value>,
200 M: FnMut(D::Error) -> Error,
201 {
202 let output_end = UncheckedSlice::checked_range_end(
203 output.len(),
204 output_index,
205 count,
206 "decoded output range exceeds destination buffer",
207 )?;
208 if count == 0 {
209 return Ok(Some(TranscodeProgress::complete(0, 0)));
210 }
211 if self.unread_len() == 0 && !self.fill_more()? {
212 return Ok(None);
213 }
214 let available_input = self.unread_len();
215 let progress = decoder
216 .transcode(
217 self.unread(),
218 0,
219 &mut output[..output_end],
220 output_index,
221 )
222 .map_err(&mut *map_error)
223 .and_then(|progress| {
224 validate_decode_progress(
225 progress,
226 0,
227 available_input,
228 output_index,
229 count,
230 )
231 })?;
232 self.consume(progress.read());
233 Ok(Some(progress))
234 }
235
236 /// Consumes unread units from the current buffer window.
237 ///
238 /// # Parameters
239 ///
240 /// * `count` - Number of unread units to discard.
241 ///
242 /// # Panics
243 ///
244 /// Panics when `count` exceeds [`Self::unread_len`].
245 pub fn consume(&mut self, count: usize) {
246 assert!(
247 count <= self.unread_len(),
248 "cannot consume beyond buffered input",
249 );
250 // SAFETY: The caller-provided count is within the unread window.
251 unsafe {
252 self.input.consume(count);
253 }
254 }
255
256 /// Copies unread units into an indexed output range without consuming them.
257 ///
258 /// # Parameters
259 ///
260 /// * `output` - Destination storage that receives a copy of unread units.
261 /// * `output_index` - Start index inside `output`.
262 /// * `count` - Number of unread units to copy.
263 ///
264 /// # Safety
265 ///
266 /// The caller must guarantee that `output_index..output_index + count` is
267 /// a valid range inside `output`, that the addition does not overflow, that
268 /// `count <= self.unread_len()`, and that the destination range does not
269 /// overlap with the unread units stored inside this buffer.
270 pub unsafe fn copy_unread_to(
271 &self,
272 output: &mut [I::Item],
273 output_index: usize,
274 count: usize,
275 ) {
276 // SAFETY: The caller guarantees the destination range and non-overlap
277 // requirements for the unread copy.
278 let unread = self.unread();
279 unsafe {
280 UncheckedSlice::copy_nonoverlapping(
281 unread,
282 0,
283 output,
284 output_index,
285 count,
286 );
287 }
288 }
289
290 /// Consumes this adapter and returns its parts.
291 ///
292 /// # Returns
293 ///
294 /// The wrapped input and the buffer holding unread units.
295 #[must_use = "the returned input and unread buffer must be handled"]
296 pub fn into_parts(self) -> (I, Buffer<I::Item>) {
297 self.input.into_parts()
298 }
299
300 /// Reads buffered units into an indexed output range.
301 ///
302 /// # Parameters
303 ///
304 /// * `output` - Destination unit storage.
305 /// * `output_index` - Start index inside `output`.
306 /// * `count` - Maximum number of units to read.
307 ///
308 /// # Returns
309 ///
310 /// The number of units copied into `output`.
311 ///
312 /// # Errors
313 ///
314 /// Returns input or buffer validation errors from the wrapped
315 /// [`qubit_io::BufferedInput`].
316 ///
317 /// # Safety
318 ///
319 /// The caller must guarantee that `output_index..output_index + count` is
320 /// a valid range inside `output` and that the addition does not overflow.
321 pub unsafe fn read_unchecked(
322 &mut self,
323 output: &mut [I::Item],
324 output_index: usize,
325 count: usize,
326 ) -> Result<usize> {
327 debug_assert!(
328 UncheckedSlice::range_fits(output.len(), output_index, count),
329 "unchecked read output range exceeds destination buffer",
330 );
331 if count == 0 {
332 return Ok(0);
333 }
334 // SAFETY: The caller guarantees the destination range is valid.
335 unsafe { self.input.read_unchecked(output, output_index, count) }
336 }
337
338 /// Decodes one codec value from the buffered unit input.
339 ///
340 /// This strict convenience method supports codecs whose decode reset and
341 /// finish phases do not emit values. Use
342 /// [`Self::read_decoded_lifecycle_with`] when those phases have output.
343 ///
344 /// # Parameters
345 ///
346 /// * `codec` - Codec used for this single-value decode.
347 /// * `map_error` - Mapper for codec-domain invalid-input errors.
348 ///
349 /// # Returns
350 ///
351 /// Returns one decoded codec value.
352 ///
353 /// # Errors
354 ///
355 /// Returns [`ErrorKind::Unsupported`] before invoking the codec or reading
356 /// input when reset or finish may emit values. Otherwise, returns I/O
357 /// errors from the wrapped input, `UnexpectedEof` when EOF occurs before a
358 /// complete value is available, `InvalidData` when the codec reports an
359 /// impossible incomplete state, or the error returned by `map_error` for
360 /// codec reset, invalid input, or codec finish failures.
361 ///
362 /// # Panics
363 ///
364 /// Panics when the codec reports more reset or finish values than its
365 /// declared bounds.
366 pub fn read_decoded_with<C, M>(
367 &mut self,
368 codec: &mut C,
369 map_error: M,
370 ) -> Result<C::Value>
371 where
372 C: Codec<Unit = I::Item>,
373 M: FnMut(C::DecodeError) -> Error,
374 {
375 TranscodeFailure::ensure_no_decode_lifecycle_output::<C>()
376 .map_err(|error| Error::new(ErrorKind::Unsupported, error))?;
377 let progress = self.read_decoded_lifecycle_with_scratch_impl(
378 codec,
379 &mut [],
380 &mut [],
381 map_error,
382 )?;
383 let (value, reset_written, finish_written) = progress.into_parts();
384 debug_assert_eq!(0, reset_written);
385 debug_assert_eq!(0, finish_written);
386 Ok(value)
387 }
388
389 /// Decodes one complete codec lifecycle and preserves every output phase.
390 ///
391 /// The method allocates independent storage for values emitted by
392 /// `decode_reset` and `decode_finish`, so neither phase can overwrite the
393 /// other.
394 ///
395 /// # Parameters
396 ///
397 /// - `codec`: Codec used to decode one complete lifecycle.
398 /// - `map_error`: Maps codec decode errors to I/O errors.
399 ///
400 /// # Returns
401 ///
402 /// Returns reset output, the main decoded value, and finish output.
403 ///
404 /// # Errors
405 ///
406 /// Returns I/O errors from the wrapped input, `UnexpectedEof` when EOF
407 /// occurs before a complete value is available, `InvalidData` when the
408 /// codec reports an impossible incomplete state, or the error returned
409 /// by `map_error` for codec reset, invalid input, or codec finish failures.
410 ///
411 /// # Panics
412 ///
413 /// Panics when the codec reports more reset or finish values than its
414 /// declared bounds.
415 pub fn read_decoded_lifecycle_with<C, M>(
416 &mut self,
417 codec: &mut C,
418 map_error: M,
419 ) -> Result<DecodeLifecycleOutput<C::Value>>
420 where
421 C: Codec<Unit = I::Item>,
422 C::Value: Default,
423 M: FnMut(C::DecodeError) -> Error,
424 {
425 assert_unit_bounds::<C>();
426 let mut reset_output = Vec::new();
427 reset_output.resize_with(C::MAX_DECODE_RESET_VALUES, C::Value::default);
428 let mut finish_output = Vec::new();
429 finish_output
430 .resize_with(C::MAX_DECODE_FINISH_VALUES, C::Value::default);
431 let progress = self.read_decoded_lifecycle_with_scratch_impl(
432 codec,
433 &mut reset_output,
434 &mut finish_output,
435 map_error,
436 )?;
437 let (value, reset_written, finish_written) = progress.into_parts();
438 reset_output.truncate(reset_written);
439 finish_output.truncate(finish_written);
440 Ok(DecodeLifecycleOutput::new(
441 reset_output,
442 value,
443 finish_output,
444 ))
445 }
446
447 /// Decodes one complete codec lifecycle into separate caller storage.
448 ///
449 /// # Parameters
450 ///
451 /// - `codec`: Codec used to decode one complete lifecycle.
452 /// - `reset_output`: Reusable storage for values emitted by
453 /// [`Codec::decode_reset`].
454 /// - `finish_output`: Reusable storage for values emitted by
455 /// [`Codec::decode_finish`].
456 /// - `map_error`: Maps codec decode errors to I/O errors.
457 ///
458 /// # Returns
459 ///
460 /// Returns the main decoded value and the initialized lengths of both
461 /// lifecycle output buffers.
462 ///
463 /// # Errors
464 ///
465 /// Returns [`ErrorKind::InvalidInput`] when either output buffer is shorter
466 /// than the corresponding codec bound. Returns I/O errors from the wrapped
467 /// input, `UnexpectedEof` when EOF occurs before a complete value is
468 /// available, `InvalidData` when the codec reports an impossible
469 /// incomplete state, or the error returned by `map_error` for codec reset,
470 /// invalid input, or codec finish failures.
471 ///
472 /// # Panics
473 ///
474 /// Panics when the codec reports more reset or finish values than its
475 /// declared bounds.
476 pub fn read_decoded_lifecycle_with_scratch<C, M>(
477 &mut self,
478 codec: &mut C,
479 reset_output: &mut [C::Value],
480 finish_output: &mut [C::Value],
481 map_error: M,
482 ) -> Result<DecodeLifecycleProgress<C::Value>>
483 where
484 C: Codec<Unit = I::Item>,
485 M: FnMut(C::DecodeError) -> Error,
486 {
487 self.read_decoded_lifecycle_with_scratch_impl(
488 codec,
489 reset_output,
490 finish_output,
491 map_error,
492 )
493 }
494
495 fn read_decoded_lifecycle_with_scratch_impl<C, M>(
496 &mut self,
497 codec: &mut C,
498 reset_output: &mut [C::Value],
499 finish_output: &mut [C::Value],
500 mut map_error: M,
501 ) -> Result<DecodeLifecycleProgress<C::Value>>
502 where
503 C: Codec<Unit = I::Item>,
504 M: FnMut(C::DecodeError) -> Error,
505 {
506 assert_unit_bounds::<C>();
507 if reset_output.len() < C::MAX_DECODE_RESET_VALUES {
508 return Err(Error::new(
509 ErrorKind::InvalidInput,
510 "decode reset output is shorter than the codec reset bound",
511 ));
512 }
513 if finish_output.len() < C::MAX_DECODE_FINISH_VALUES {
514 return Err(Error::new(
515 ErrorKind::InvalidInput,
516 "decode finish output is shorter than the codec finish bound",
517 ));
518 }
519 let reset_written = unsafe {
520 // SAFETY: The reset output length check above reserves the codec's
521 // declared decode-reset output bound.
522 codec.decode_reset(reset_output, 0)
523 }
524 .map_err(&mut map_error)?;
525 assert!(
526 reset_written <= C::MAX_DECODE_RESET_VALUES,
527 "Codec::decode_reset wrote beyond its reset bound",
528 );
529
530 let value = CodecDecodeDriver::new(&mut self.input)
531 .read_one(codec, &mut map_error)?;
532
533 let finish_written = unsafe {
534 // SAFETY: The finish output length check above reserves the
535 // codec's declared decode-finish output bound.
536 codec.decode_finish(finish_output, 0)
537 }
538 .map_err(&mut map_error)?;
539 assert!(
540 finish_written <= C::MAX_DECODE_FINISH_VALUES,
541 "Codec::decode_finish wrote beyond its finish bound",
542 );
543 Ok(DecodeLifecycleProgress::new(
544 value,
545 reset_written,
546 finish_written,
547 ))
548 }
549
550 /// Runs decoder reset into an indexed output range.
551 ///
552 /// This method does not read or consume buffered input units.
553 ///
554 /// # Errors
555 ///
556 /// Returns invalid output ranges, insufficient declared output capacity,
557 /// capacity errors, or reset errors mapped by `map_error`.
558 ///
559 /// # Panics
560 ///
561 /// Panics when the decoder reports writing more values than its declared
562 /// reset bound.
563 pub fn reset<D, M, Value>(
564 &self,
565 decoder: &mut D,
566 map_error: &mut M,
567 output: &mut [Value],
568 output_index: usize,
569 count: usize,
570 ) -> Result<usize>
571 where
572 D: Transcoder<Input = I::Item, Output = Value>,
573 M: FnMut(D::Error) -> Error,
574 {
575 let required = decoder
576 .max_reset_output_len()
577 .map_err(capacity_to_io_error)?;
578 let output_end = UncheckedSlice::checked_range_end(
579 output.len(),
580 output_index,
581 count,
582 "reset output range exceeds destination buffer",
583 )?;
584 if count < required {
585 return Err(Error::new(
586 ErrorKind::InvalidData,
587 "insufficient output for decoder reset bound",
588 ));
589 }
590 let output = &mut output[..output_end];
591 let written = decoder
592 .reset(output, output_index)
593 .map_err(&mut *map_error)?;
594 assert!(written <= required, "reset wrote beyond its bound");
595 Ok(written)
596 }
597
598 /// Decodes values into an indexed output range using a streaming
599 /// [`Transcoder`].
600 ///
601 /// # Parameters
602 ///
603 /// * `decoder` - Streaming decoder used for this operation.
604 /// * `map_error` - Function mapping transcode errors into I/O errors.
605 /// * `output` - Destination value storage.
606 /// * `output_index` - Start index inside `output`.
607 /// * `count` - Maximum number of values to write.
608 ///
609 /// # Returns
610 ///
611 /// The number of values written. Incomplete EOF tails are left buffered
612 /// and reported as `Ok(written)`, so callers can apply their own EOF
613 /// policy.
614 ///
615 /// # Errors
616 ///
617 /// Returns input errors, invalid output ranges, capacity errors from the
618 /// internal buffer, or transcode errors mapped by `map_error`.
619 pub fn transcode<D, M, Value>(
620 &mut self,
621 decoder: &mut D,
622 map_error: &mut M,
623 output: &mut [Value],
624 output_index: usize,
625 count: usize,
626 ) -> Result<usize>
627 where
628 D: Transcoder<Input = I::Item, Output = Value>,
629 M: FnMut(D::Error) -> Error,
630 {
631 let output_end = UncheckedSlice::checked_range_end(
632 output.len(),
633 output_index,
634 count,
635 "decoded output range exceeds destination buffer",
636 )?;
637 if count == 0 {
638 return Ok(0);
639 }
640 let output = &mut output[..output_end];
641 let mut written_total = 0;
642 loop {
643 if self.unread_len() == 0 && !self.fill_more()? {
644 return Ok(written_total);
645 }
646 let units = self.unread();
647 let available_input = units.len();
648 let remaining_output = count - written_total;
649 let progress = decoder
650 .transcode(units, 0, output, output_index + written_total)
651 .map_err(&mut *map_error)?;
652 let progress = validate_decode_progress(
653 progress,
654 0,
655 available_input,
656 output_index + written_total,
657 remaining_output,
658 )?;
659 let consumed = progress.read();
660 let written = progress.written();
661 self.consume(consumed);
662 written_total += written;
663 match progress.status() {
664 TranscodeStatus::Complete => {
665 if written_total == count {
666 return Ok(written_total);
667 }
668 }
669 TranscodeStatus::NeedOutput { .. } => {
670 return Ok(written_total);
671 }
672 TranscodeStatus::NeedInput { required, .. } => {
673 if self.fill_until(required.get())? {
674 continue;
675 }
676 return Ok(written_total);
677 }
678 }
679 }
680 }
681
682 /// Finishes a streaming decoder into an indexed output range.
683 ///
684 /// # Parameters
685 ///
686 /// * `decoder` - Streaming decoder whose final output is being collected.
687 /// * `map_error` - Function mapping transcode errors into I/O errors.
688 /// * `output` - Destination value storage.
689 /// * `output_index` - Start index inside `output`.
690 /// * `count` - Maximum number of finish values to write.
691 ///
692 /// # Returns
693 ///
694 /// The number of values written by the decoder finish operation.
695 ///
696 /// # Errors
697 ///
698 /// Returns invalid output ranges, capacity errors, or transcode
699 /// finalization errors mapped to I/O errors.
700 ///
701 /// # Panics
702 ///
703 /// Panics when the decoder reports writing more values than its
704 /// [`Transcoder::max_finish_output_len`] bound.
705 pub fn finish<D, M, Value>(
706 &self,
707 decoder: &mut D,
708 map_error: &mut M,
709 output: &mut [Value],
710 output_index: usize,
711 count: usize,
712 ) -> Result<usize>
713 where
714 D: Transcoder<Input = I::Item, Output = Value>,
715 M: FnMut(D::Error) -> Error,
716 {
717 let required = decoder
718 .max_finish_output_len()
719 .map_err(capacity_to_io_error)?;
720 // Validate the caller-supplied count range first (InvalidInput).
721 let output_end = UncheckedSlice::checked_range_end(
722 output.len(),
723 output_index,
724 count,
725 "finish output range exceeds destination buffer",
726 )?;
727 // `count` is the caller's declared writable finish range. The
728 // destination slice may be larger, but passing extra capacity to the
729 // decoder would allow it to write beyond the range the caller granted.
730 if count < required {
731 return Err(Error::new(
732 ErrorKind::InvalidData,
733 "insufficient output for decoder finish bound",
734 ));
735 }
736 let output = &mut output[..output_end];
737 let written = decoder
738 .finish(output, output_index)
739 .map_err(&mut *map_error)?;
740 assert!(written <= required, "finish wrote beyond its bound");
741 Ok(written)
742 }
743}
744
745impl<I> TranscodeDecodeInput<I>
746where
747 I: Input<Item = u8> + Seekable<Unit = u8>,
748{
749 /// Seeks the wrapped byte input and discards buffered bytes after success.
750 ///
751 /// # Parameters
752 ///
753 /// * `position` - Target seek position.
754 ///
755 /// # Returns
756 ///
757 /// The new stream position reported by the wrapped input.
758 ///
759 /// # Errors
760 ///
761 /// Returns seek errors from the wrapped input.
762 pub fn seek(&mut self, position: SeekFrom) -> Result<u64> {
763 self.input.seek_to(position)
764 }
765}
766
767impl<I> TranscodeDecodeInput<I>
768where
769 I: Input,
770 I::Item: Copy + Default,
771{
772 /// Refills the underlying buffer.
773 fn fill_more(&mut self) -> Result<bool> {
774 self.input.fill_more()
775 }
776}
777
778impl<I> Read for TranscodeDecodeInput<I>
779where
780 I: Input<Item = u8>,
781{
782 /// Reads raw bytes through the internal buffer.
783 fn read(&mut self, output: &mut [u8]) -> Result<usize> {
784 // SAFETY: The full output slice is a valid destination range.
785 unsafe { self.read_unchecked(output, 0, output.len()) }
786 }
787}
788
789impl<I> Seek for TranscodeDecodeInput<I>
790where
791 I: Input<Item = u8> + Seekable<Unit = u8>,
792{
793 /// Seeks the wrapped byte input and discards buffered bytes after success.
794 fn seek(&mut self, position: SeekFrom) -> Result<u64> {
795 self.seek(position)
796 }
797}
798
799impl<I> fmt::Debug for TranscodeDecodeInput<I>
800where
801 I: Input,
802 I::Item: Copy + Default,
803 BufferedInput<I>: fmt::Debug,
804{
805 /// Formats this buffered decode input for debugging.
806 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
807 formatter
808 .debug_struct("TranscodeDecodeInput")
809 .field("input", &self.input)
810 .finish()
811 }
812}
813
814/// Converts a capacity planning failure into an I/O error.
815fn capacity_to_io_error(error: crate::CapacityError) -> Error {
816 Error::new(ErrorKind::InvalidData, error)
817}
818
819/// Converts an allocation failure into an I/O boundary error.
820fn allocation_to_io_error(error: std::collections::TryReserveError) -> Error {
821 Error::new(ErrorKind::OutOfMemory, error)
822}