feat(file): carry the name a file already has - #815
Merged
Conversation
`abstract::File` knew where a file was but not what it was called. The name was only reachable through `disk_path`, which a memory file does not have — so `file_type_by_name` could offer markdown for a `.md` on disk and nothing for the same bytes uploaded from a browser. `File::name()` asks the file itself: the file name for one on disk, the entry name for one inside a zip or cfb, and what `File::from_memory(data, name)` was given for one in memory, defaulting to none. Reading a file into memory takes the name with the bytes, so a `MemoryFile` built from a `DiskFile` still knows it is `about.odt`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wana5y5HtzoDq5yMkKvAMS
The name a file carries is only useful where a caller can read it, and where a
caller handing over bytes can set it.
- python: `File.name()`, and `File.from_memory(data, name="")`.
- jni: `File.name()`.
- apple: `File.name`.
- wasm: `open(bytes, {name})` and `detect(bytes, name)` take the browser
`File.name` the bytes were dropped in under, and `Document.fileName` hands it
back. The js wrapper defaults it, so no existing call changes.
JNI and Apple never took bytes in the first place — their `File` is a path — so
there is nothing to name there beyond what the path and the archive entry
already say.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wana5y5HtzoDq5yMkKvAMS
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ShzTYFSnbXc66ERBiTxhDi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 Generated with Claude Code
abstract::Fileknew where a file was but not what it was called. The namewas only reachable through
disk_path, which a memory file does not have — sofile_type_by_name(#814) could offer markdown for a.mdon disk and nothingfor the same bytes arriving from a download or a browser upload.
Core
abstract::File::name(), and the publicFile::name(): the file's own name,without any directory.
DiskFile— the basename of its path.MemoryFile— what it was constructed with, empty by default.FileInZip/FileInCfb— the entry name.File::from_memory(std::string data, std::string name = {})— the new secondargument is how a caller with bytes and no path says what they were called.
The default keeps every existing call site compiling and behaving as before.
MemoryFile(const abstract::File &)takes the name along with the bytes, soreading a file off disk into memory does not forget it is
about.odt.open_strategy::file_type_by_namereads the extension offname()ratherthan off
disk_path(). A name still only ever adds a candidate the bytesalready allow, and only for a type no content probe can produce (markdown,
html) — so
File::from_memory(md, "notes.md")now decodes as markdown, and azip called
notes.mdis still a zip.Bindings
File.name()File.from_memory(data, name="")File.name()File.nameDocument.fileNameodr.open(bytes, { name }),odr.detect(bytes, name)JNI and Apple never took bytes in the first place — their
Fileis path-only —so there is nothing to name there beyond what the path, or the archive entry,
already says. The wasm JS wrapper defaults the name, so no existing call
changes;
wasm/README.mdand the example page now pass the browser'sFile.name, which is exactly the case the core change was for.Testing
File.name_is_the_file_name_on_disk,File.from_memory_is_unnamed_unless_told,File.a_file_read_into_memory_keeps_its_name,File.an_archive_entry_is_named_by_its_entry, andodr.a_named_file_in_memory_is_offered_its_type— bytes namednotes.mdlist and open as markdown. Full
odr_test: 1425 passed, 6 skipped (the same6 as on main).
node --test38 passed, XCTest 26 passed —each including the new cases.
-Wall -Wextra -Wmissing-field-initializers -Werror -fsyntax-only(emscripten's clang for the wasm one); clang-tidyreports only findings that pre-date this change.