Expand description
Slice adapters — view a byte sub-range of any BlockRead as its own
device. Useful any time you want to feed a fragment of a larger
device to a consumer that expects a whole block source — partition
probes, image-file extents, mmap-style views, fuzzer harnesses.
Three variants:
SliceReaderborrows the parent, lifetime-tied. Cheaper when the parent outlives the slice and you can express that statically.OwnedSliceholds anArcto the parent. Use when the parent’s lifetime can’t be expressed in a borrow (FFI handles, slice handed across thread boundaries, etc.).OwnedRwSliceholds anArc<dyn BlockDevice>and propagates writes to the parent.
The first two are strictly read-only: the default Err(ReadOnly)
write path from BlockDevice applies.
§Which error an out-of-range request gets
All three share one range check — SliceGeometry::rebase — and it
answers in two different currencies depending on the direction of the
request:
request outside [0, length) | error |
|---|---|
| read | Error::ShortRead with got: 0 |
| write | Error::OutOfBounds |
The asymmetry is deliberate. A slice exists to be substitutable for a
real device of size length, and a real device — FileDevice —
answers a read that begins at or past its end with exactly
ShortRead { offset, want, got: 0 }. A slice that answered
OutOfBounds would be distinguishable from the thing it stands in
for, and every caller that already handles end-of-device would need a
second arm to cope with slices. Writes have no partial-write variant
to stay consistent with, and a caller that overran a write needs the
device size in order to clamp and retry — which is what
Error::OutOfBounds carries and Error::ShortRead does not.
The match is on the variant, not on got. A slice refuses an
out-of-range read before it touches the parent, so it reports got: 0
and leaves the buffer untouched — including for a read that begins
inside the slice and runs off its end, where FileDevice would have
copied the readable prefix and reported its length. got counts bytes
actually delivered, and a slice delivers none.
This governs the slice’s own range only. A request that is inside
[0, length) is forwarded to the parent, and whatever the parent says
about it — including Error::OutOfBounds from a container reader
that knows its virtual size — comes back unchanged.
Structs§
- Owned
RwSlice - Owned, read-WRITE slice over an
Arc<dyn BlockDevice>. Use when the parent is writable and the slice should propagate writes (e.g. an individual partition handed to a filesystem driver). - Owned
Slice - Owned slice over an
Arc<dyn BlockRead>. Use when the parent’s lifetime can’t be expressed in a borrow — e.g. when the slice is handed across an FFI boundary or stored in a long-lived struct. - Slice
Reader - Borrowed slice of a parent
BlockRead.