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}