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}