Skip to main content

qubit_io/std_io/ext/
seek_ext.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
9//! Extension operations for inspecting standard seekable streams.
10
11use std::io::Result;
12use std::io::Seek;
13
14use crate::std_io::ext::internal::seek_ext_impl;
15
16/// Extension methods for [`Seek`] values.
17///
18/// `SeekExt` provides stable, position-preserving helpers for seekable streams.
19/// The methods are implemented for every type that implements [`Seek`],
20/// including `dyn Seek` trait objects.
21///
22/// # Examples
23///
24/// ```
25/// use std::io::Cursor;
26/// use std::io::Seek;
27///
28/// use qubit_io::std_io::ext::SeekExt;
29///
30/// let mut stream = Cursor::new(b"hello".to_vec());
31/// stream.set_position(2);
32/// assert_eq!(stream.stream_size()?, 5);
33/// assert_eq!(stream.stream_position()?, 2);
34/// # Ok::<(), std::io::Error>(())
35/// ```
36pub trait SeekExt: Seek {
37    /// Gets the stream size without changing the final stream position.
38    ///
39    /// The original position is captured with [`Seek::stream_position`], then
40    /// the stream is moved to the end to measure its size, and finally the
41    /// original position is restored.
42    ///
43    /// # Compatibility
44    /// If the standard library adds an equivalent `Seek::stream_size` method,
45    /// this extension method may be deprecated in a future release.
46    ///
47    /// # Returns
48    /// The stream size in bytes.
49    ///
50    /// # Errors
51    /// Returns an error when reading the current position, seeking to the end,
52    /// or restoring the original position fails. If restoring fails, the
53    /// restore error is returned because the caller's stream position contract
54    /// was not preserved.
55    fn stream_size(&mut self) -> Result<u64>;
56}
57
58impl<T> SeekExt for T
59where
60    T: Seek + ?Sized,
61{
62    /// Gets the stream size without changing its final position.
63    ///
64    /// # Returns
65    /// The stream size in bytes.
66    ///
67    /// # Errors
68    /// Returns an error when querying, changing, or restoring the stream
69    /// position fails.
70    #[inline(always)]
71    fn stream_size(&mut self) -> Result<u64> {
72        let mut stream = self;
73        seek_ext_impl::stream_size(&mut stream)
74    }
75}