qubit_io/traits/buf_read_seek.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::io::{
11 BufRead,
12 Seek,
13};
14
15/// Object-safe capability trait for values that can be buffered-read and repositioned.
16///
17/// `BufReadSeek` gives the common [`BufRead`] + [`Seek`] combination a named
18/// trait for APIs that need buffered reads and random access through trait
19/// objects. Typical use cases include line-oriented parsers over seekable files
20/// and buffered readers that still need to jump between sections.
21///
22/// The trait adds no methods of its own. All operations come from the
23/// standard-library supertraits, and every type implementing both [`BufRead`]
24/// and [`Seek`] automatically implements `BufReadSeek`.
25///
26/// # Examples
27///
28/// ```rust
29/// use qubit_io::BufReadSeek;
30/// use std::io::{BufRead, BufReader, Cursor, SeekFrom};
31///
32/// fn read_after_prefix(input: &mut dyn BufReadSeek) -> std::io::Result<String> {
33/// input.seek(SeekFrom::Start(4))?;
34///
35/// let mut line = String::new();
36/// input.read_line(&mut line)?;
37/// Ok(line)
38/// }
39///
40/// let cursor = Cursor::new(b"abc\ndef".to_vec());
41/// let mut reader = BufReader::new(cursor);
42/// assert_eq!(read_after_prefix(&mut reader)?, "def");
43/// # Ok::<(), std::io::Error>(())
44/// ```
45pub trait BufReadSeek: BufRead + Seek {}
46
47impl<T> BufReadSeek for T where T: BufRead + Seek + ?Sized {}