Skip to content

refactor(api)!: one way to ask what a file is - #835

Merged
andiwand merged 2 commits into
mainfrom
refactor/one-way-to-detect
Sep 6, 2026
Merged

refactor(api)!: one way to ask what a file is#835
andiwand merged 2 commits into
mainfrom
refactor/one-way-to-detect

Conversation

@andiwand

@andiwand andiwand commented Sep 6, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

PR 5 of the v7 API plan.

Twelve public entry points answered what is this file. This leaves four —
two questions over two input types.

The four duplicate statics

DecodedFile::list_file_types and DecodedFile::mimetype (×2 each) were the
implementation; odr::list_file_types and odr::mimetype were one-line
forwards to them. The bodies move up to the free functions and the statics go.

The clearest evidence this was a real fork and not a harmless alias: the
bindings picked different ones.
apple/src/ODRFile.mm called
odr::DecodedFile::list_file_types, jni/src/jni_core.cpp called
odr::list_file_types, for the same operation.

DocumentFile::type and ::meta

FileType DocumentFile::type(const File &file) {
  return DocumentFile(file).file_type();   // decodes the whole file
}

Four statics that decoded an entire document to read one field, and threw
NoDocumentFile for anything that was not a document — so type(some.png) was
an exception rather than FileType::portable_network_graphics.
open(...).file_type() and .file_meta() answer without the narrowing.

Bindings

gone
Java DocumentFile.typeByPath, DocumentFile.metaByPath
Python DocumentFile.type_by_file / type_by_path / meta_by_file / meta_by_path
ObjC unchanged surface; listFileTypes/mimetype now call the free functions

The python binding's own comment is a small monument to the problem it had —
"type/meta are overloaded on File and path, so the address of either is
ambiguous; name the signature"
— four def_statics existing to disambiguate
an overload set that did not need to exist.

Tests

FileTest.documentFileByPath tested the removed statics; rewritten to assert
what it was actually after, that a path names an odt, through
Odr.open(path).fileType() / .fileMeta(). test_file.py's two cases
likewise.

Net −131/+39.

Verified

Full build clean. 222 gtests (File*, *Csv*, *Markdown*, *Xml*,
*Flat*, *Document*), 69 python tests, JNI junit via ctest --test-dir jni
— all pass.

Migration

DecodedFile::mimetype(path)        →  odr::mimetype(path)
DecodedFile::list_file_types(path) →  odr::list_file_types(path)
DocumentFile::type(path)           →  odr::open(path).file_type()
DocumentFile::meta(path)           →  odr::open(path).file_meta()

andiwand and others added 2 commits September 6, 2026 15:34
Twelve entry points answered the question. Four were the free functions; four
more were DecodedFile statics the free functions forwarded to, so the same
call had two spellings and the bindings picked different ones - apple went
through the statics, jni through the free function. The bodies move to the
free functions and the statics go.

The other four were DocumentFile::type and ::meta, which decoded the entire
file to read a single field and threw NoDocumentFile for anything that was not
a document. open(...).file_type() and .file_meta() say the same thing without
the narrowing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hxDa2rev11eLUEJZJ5nmz
detect() reached for the statics rather than the free functions, and nothing
local builds wasm, so it went unnoticed until a syntax check against the
emscripten toolchain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hxDa2rev11eLUEJZJ5nmz
@andiwand
andiwand force-pushed the refactor/one-way-to-detect branch from 3ba5f19 to 0e2a00c Compare September 6, 2026 13:36
@andiwand
andiwand merged commit 96d1100 into main Sep 6, 2026
25 checks passed
@andiwand
andiwand deleted the refactor/one-way-to-detect branch September 6, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant