Skip to main content

base_scheduler/
file_reader.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::{BufferResult, Cancellation, IoBufMut};
5use std::{future::Future, io};
6
7/// Scheduler-bound, sequential access to a file's readable direction. Construct through [`FileReading`](crate::FileReading). Separate handles permit overlapping operations, but shared-cursor operations have no ordering guarantee across handles.
8pub trait FileReader: Send {
9    /// Read once at the file's shared OS cursor, returning a possibly short count and the original owner on every result. Cancellation cannot roll back transferred bytes or cursor changes.
10    fn read<B: IoBufMut>(
11        &mut self,
12        buffer: B,
13        cancellation: &Cancellation,
14    ) -> impl Future<Output = BufferResult<B>> + Send;
15
16    /// Read once at an explicit offset. Offsets must fit in `i64`. Unix implementations leave the shared cursor unchanged; Windows implementations may use `seek_read`, which changes it. The handle maintains no private cursor.
17    fn read_at<B: IoBufMut>(
18        &mut self,
19        buffer: B,
20        offset: u64,
21        cancellation: &Cancellation,
22    ) -> impl Future<Output = BufferResult<B>> + Send;
23
24    /// Await admission separately from collecting the original owner. Accepted work can complete independently of polling the returned future. The fallback completes the ordinary operation before returning; backends can admit independently progressing work earlier. Pre-cancellation rejects admission and returns the unchanged owner.
25    fn read_submit<B: IoBufMut>(
26        &mut self,
27        buffer: B,
28        cancellation: &Cancellation,
29    ) -> impl Future<
30        Output = Result<
31            impl Future<Output = BufferResult<B>> + Send + 'static,
32            (crate::OperationError, B),
33        >,
34    > + Send {
35        async move {
36            if let Err(error) = cancellation.check() {
37                return Err((error.into(), buffer));
38            }
39            let result = self.read(buffer, cancellation).await;
40            Ok(async move { result })
41        }
42    }
43
44    /// Await admission separately from collecting the original owner. Accepted work can complete independently of polling the returned future. The fallback completes the ordinary operation before returning; backends can admit independently progressing work earlier. Pre-cancellation rejects admission and returns the unchanged owner.
45    fn read_at_submit<B: IoBufMut>(
46        &mut self,
47        buffer: B,
48        offset: u64,
49        cancellation: &Cancellation,
50    ) -> impl Future<
51        Output = Result<
52            impl Future<Output = BufferResult<B>> + Send + 'static,
53            (crate::OperationError, B),
54        >,
55    > + Send {
56        async move {
57            if let Err(error) = cancellation.check() {
58                return Err((error.into(), buffer));
59            }
60            let result = self.read_at(buffer, offset, cancellation).await;
61            Ok(async move { result })
62        }
63    }
64
65    /// Stop admission and await accepted operation retirement without cancellation. Repeated close is safe; dropping a pending close is not a retirement barrier. This does not close the underlying file. Drop the retired handle before exclusive file close.
66    fn close(&mut self) -> impl Future<Output = io::Result<()>> + Send;
67}