qubit_io/traits/seekable_byte_output.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
9use crate::ByteOutput;
10use crate::SeekableOutput;
11
12/// A synchronous output that transfers and seeks in bytes.
13///
14/// This trait adds no methods. Every [`SeekableOutput`] with both
15/// `Item = u8` and `Unit = u8`, including unsized streams, implements it
16/// automatically. Implement the underlying output and seek traits instead.
17///
18/// # Examples
19/// A byte cursor can be written and repositioned through the trait object:
20///
21/// ```
22/// use std::io::{Cursor, Result, SeekFrom};
23/// use qubit_io::SeekableByteOutput;
24/// fn rewind(stream: &mut dyn SeekableByteOutput) -> Result<u64> { stream.seek_to(SeekFrom::Start(0)) }
25/// let mut cursor = Cursor::new(Vec::<u8>::new());
26/// let stream: &mut dyn SeekableByteOutput = &mut cursor;
27/// stream.write_fully(b"QBIT")?;
28/// assert_eq!(stream.seek_to(SeekFrom::Current(0))?, 4);
29/// assert_eq!(rewind(stream)?, 0);
30/// stream.write_fully(b"R")?;
31/// assert_eq!(cursor.into_inner(), b"RBIT");
32/// # Ok::<(), std::io::Error>(())
33/// ```
34/// Streams with a different item type do not satisfy this bound:
35///
36/// ```compile_fail
37/// use qubit_io::{SeekableByteOutput, SeekableOutput};
38///
39/// fn accept(stream: impl SeekableByteOutput) {}
40///
41/// fn reject(stream: impl SeekableOutput<Item = char, Unit = char>) {
42/// accept(stream);
43/// }
44/// ```
45///
46/// The seek unit must also match the transferred items:
47///
48/// ```compile_fail
49/// use qubit_io::{Output, Seekable, SeekableByteOutput};
50///
51/// fn accept(stream: impl SeekableByteOutput) {}
52///
53/// fn reject(stream: impl Output<Item = u8> + Seekable<Unit = char>) {
54/// accept(stream);
55/// }
56/// ```
57pub trait SeekableByteOutput: ByteOutput + SeekableOutput<Item = u8, Unit = u8> {
58 // empty
59}
60
61impl<T: SeekableOutput<Item = u8, Unit = u8> + ?Sized> SeekableByteOutput for T {}