Reword FR-RAW-2's mechanism to the one that serves its purpose
FR-RAW-2 required RAW decoding to sit behind "a trait taking a SourceRef, not a filesystem path". The purpose is met — `dr_decode::decode` takes `&[u8]` and the crate has no path-based entry point anywhere — and the mechanism is not, because a decoder taking a SourceRef would be a worse design than the one built. A SourceRef is opaque. The only thing that turns one into bytes is `Storage`, which lives in platform/dr-plat, so a decoder taking a SourceRef must take a Storage with it: retry, permission loss and remote fetching move inside the decoder, and the decoder becomes constructible only where a Storage exists. Bytes in, image out, is narrower and more portable — the decoder cannot know where its input came from, which is the property the requirement wants. The Nextcloud case is the one a byte-oriented API looks like it should lose, and it is the clearest illustration that it does not. `dr_decode::HEADER_BYTES` declares how much of a file the decoder needs in order to read metadata, and `import.rs` fetches exactly that range through `Storage::read_range` before calling `dr_decode::metadata`. The decoder states a requirement; the storage layer satisfies it. A decoder holding its own SourceRef would have had to carry the range policy itself. The trait half of the clause is left standing and unmet. There is one decoder reached through free functions, so "a second implementation may be added without changing callers" is still outstanding work rather than a description. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+28
-4
@@ -206,10 +206,34 @@ destructive action, since that figure is what tells the user whether they meant
|
||||
CR3), Nikon (NEF), Sony (ARW), Fujifilm (RAF, including X-Trans), Panasonic (RW2), Olympus (ORF),
|
||||
Adobe DNG. Additional formats are a coverage goal, not a launch blocker.
|
||||
|
||||
**FR-RAW-2 — Decoder abstraction.** RAW decoding sits behind a trait taking a `SourceRef`
|
||||
(FR-CAT-1a), not a filesystem path, so the same decoder works over a local file, an Android SAF
|
||||
document, or a byte range fetched from Nextcloud. A second implementation may be added for broader
|
||||
camera coverage without changing callers (D2).
|
||||
**FR-RAW-2 — Decoder abstraction.** RAW decoding takes **bytes**, never a filesystem path and never
|
||||
a reference it would have to resolve. Resolving a `SourceRef` (FR-CAT-1a) to bytes is
|
||||
`Storage::open`'s job and happens at the caller, so the same decoder works over a local file, an
|
||||
Android SAF document, or a byte range fetched from Nextcloud. A second implementation may be added
|
||||
for broader camera coverage without changing callers (D2).
|
||||
|
||||
*On the change of mechanism.* This clause used to require "a trait taking a `SourceRef`". The
|
||||
purpose — that no decoder API takes a path, so nothing in the decode path assumes a filesystem —
|
||||
is met and is not in question: `dr_decode::decode` takes `&[u8]`, and there is no path-based entry
|
||||
point in the crate. The mechanism was wrong, and stating it that way would have made the design
|
||||
worse.
|
||||
|
||||
A `SourceRef` is opaque by construction; the only thing that turns one into readable bytes is
|
||||
`Storage`, in `platform/dr-plat`. A decoder taking a `SourceRef` would therefore have to take a
|
||||
`Storage` alongside it, which moves retry, permission loss and remote fetching inside the decoder
|
||||
and leaves it constructible only where a `Storage` exists. Bytes in, image out, is both narrower and
|
||||
more portable: the decoder has no idea where its input came from, which is the property this
|
||||
requirement is actually asking for.
|
||||
|
||||
It also serves the Nextcloud case better rather than worse, which is the one a byte-oriented API
|
||||
looks like it would lose. `dr_decode::HEADER_BYTES` declares how much of a file the decoder needs to
|
||||
read metadata, and `import.rs` fetches exactly that range through `Storage::read_range` before
|
||||
calling `dr_decode::metadata`. The decoder states its requirement and the storage layer satisfies
|
||||
it; a decoder holding its own `SourceRef` would have had to implement the range policy itself.
|
||||
|
||||
What is genuinely not built is the trait. There is one decoder, reached through free functions, so
|
||||
"without changing callers" is a claim nothing yet tests. The clause stands as written and is
|
||||
outstanding work, not a satisfied one.
|
||||
|
||||
**FR-RAW-3 — Sensor data handling.** Correctly apply per-camera black/white levels, CFA pattern
|
||||
identification, and camera-native colour matrices. Demosaic quality shall be selectable, with at
|
||||
|
||||
Reference in New Issue
Block a user