feat(infer): resolve known content types via mimetype instead of no-op#61
Conversation
|
Warning Review limit reached
More reviews will be available in 20 minutes and 20 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
multipartkit/infer.content_type_from_filenameandcontent_type_from_byteswere default no-ops that returnedNonefor every input, including well-known types ("a.png", the PNG magic header, etc.). This made the publicinferhelpers surprising: a caller asking for the content type ofphoto.pnggotNone. Issue #59 asks for real inference; the chosen resolution (option 1) is to delegate to the siblingnao1215/mimetypepackage, which already maintains the IANA + magic-byte tables.This reverses the v0.13.0 (#52) decision to ship these helpers as documented no-ops. That decision was pinned by
test/regression_infer_default_test.gleam; this PR rewrites that file to assert the new contract.Changes
content_type_from_filenameandcontent_type_from_bytesnow delegate tomimetype.filename_to_mime_type_strict/mimetype.detect_strict, returningSome(mimetype.essence_of(_))for recognised input andNoneotherwise (option.from_result |> option.map(essence_of)).nao1215/mimetypeis added as a runtime dependency (>= 0.24.0 and < 1.0.0).Inference into the form builder stays opt-in.
infer.default_inferer()is intentionally kept a no-op, soadd_file_autostill falls through toapplication/octet-streamand never changes a content type implicitly. A newinfer.builtin_inferer()wires the two helpers into anInferer, so callers can opt in withform.add_file_auto_with(form, ..., infer.builtin_inferer())without writing themimetypewiring themselves.test/regression_infer_default_test.gleamis rewritten to assert: the #59 DoD (known extensions and magic-byte signatures resolve to the expected MIME strings; unknown / empty input isNone), thatdefault_inferer()is still a no-op, and thatbuiltin_inferer()resolves.Docstrings, the README feature bullet, and the CHANGELOG are updated.
Design Decisions
Option 1 (delegate to
mimetype) was chosen over option 2 (inline a built-in table) because an inline table would duplicate, and inevitably drift from, the table that the siblingmimetypepackage already maintains — the very duplication theinferdocstrings already steered callers away from. Delegating gives full IANA + magic-byte coverage with no duplicate maintenance.default_inferer()is deliberately left a no-op rather than wired tomimetype, soadd_file_auto's behaviour is unchanged and inference remains an explicit opt-in (builtin_inferer()or a customInferer). This keeps the form builder from silently changing content types when the dependency resolves an extension.Notes
This PR also restores the
## [0.13.0] - 2026-05-20CHANGELOG header, which was accidentally dropped in #60 — without it, the released 0.13.0 entries (#52, #51, #50) were sitting under[Unreleased].mimetype.detect_strictclassifies arbitrary printable-ASCII input astext/plain; this is reachable only through the direct helper /builtin_inferer(never throughadd_file_auto), and is documented oncontent_type_from_bytes.Closes #59