Skip to main content

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