Current section
Files
Jump to
Current section
Files
src/multipartkit@infer.erl
-module(multipartkit@infer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/multipartkit/infer.gleam").
-export([default_inferer/0, content_type_from_filename/1, content_type_from_bytes/1, builtin_inferer/0]).
-export_type([inferer/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type inferer() :: {inferer,
fun((binary()) -> gleam@option:option(binary())),
fun((bitstring()) -> gleam@option:option(binary()))}.
-file("src/multipartkit/infer.gleam", 47).
-spec noop_filename(binary()) -> gleam@option:option(binary()).
noop_filename(_) ->
none.
-file("src/multipartkit/infer.gleam", 51).
-spec noop_bytes(bitstring()) -> gleam@option:option(binary()).
noop_bytes(_) ->
none.
-file("src/multipartkit/infer.gleam", 43).
?DOC(
" Inferer that always returns `None`.\n"
"\n"
" `add_file_auto` uses this and therefore always emits\n"
" `application/octet-stream` unless the host swaps in a real inferer via\n"
" `add_file_auto_with` (for example `builtin_inferer`, or one of your\n"
" own). Keeping the default a no-op means `add_file_auto` never changes\n"
" the content type implicitly — inference is always something the caller\n"
" opts into.\n"
).
-spec default_inferer() -> inferer().
default_inferer() ->
{inferer, fun noop_filename/1, fun noop_bytes/1}.
-file("src/multipartkit/infer.gleam", 86).
?DOC(
" Infer a content type from a filename's extension.\n"
"\n"
" Delegates to `nao1215/mimetype`'s extension database: returns\n"
" `Some(mime)` for a recognised extension (for example `\"photo.png\"` ->\n"
" `Some(\"image/png\")`, `\"doc.pdf\"` -> `Some(\"application/pdf\")`,\n"
" `\"data.json\"` -> `Some(\"application/json\")`) and `None` when the path\n"
" has no usable extension (`\"\"`, `\"README\"`) or the extension is not in\n"
" the database (`\"a.zzznosuch\"`).\n"
"\n"
" This is a convenience over the `mimetype` dependency; for the form\n"
" builder, wire it in with `form.add_file_auto_with(form, ...,\n"
" builtin_inferer())` (or build your own `Inferer`).\n"
).
-spec content_type_from_filename(binary()) -> gleam@option:option(binary()).
content_type_from_filename(Filename) ->
_pipe = mimetype:filename_to_mime_type_strict(Filename),
_pipe@1 = gleam@option:from_result(_pipe),
gleam@option:map(_pipe@1, fun mimetype:essence_of/1).
-file("src/multipartkit/infer.gleam", 107).
?DOC(
" Infer a content type from a body's leading bytes (magic-number\n"
" signature).\n"
"\n"
" Delegates to `nao1215/mimetype`'s detector: returns `Some(mime)` for a\n"
" recognised signature (for example the 8-byte PNG header ->\n"
" `Some(\"image/png\")`, `<<0xFF, 0xD8, 0xFF, ...>>` ->\n"
" `Some(\"image/jpeg\")`, `\"%PDF-...\"` -> `Some(\"application/pdf\")`) and\n"
" `None` for the empty `BitArray` or input whose bytes match no\n"
" supported signature. Note `mimetype`'s detector classifies arbitrary\n"
" printable-ASCII input as `Some(\"text/plain\")`, so a text body with no\n"
" stronger signature resolves to `text/plain` rather than `None`.\n"
"\n"
" As with `content_type_from_filename`, this is a convenience over the\n"
" `mimetype` dependency; wire it into the form builder with\n"
" `form.add_file_auto_with(form, ..., builtin_inferer())`.\n"
).
-spec content_type_from_bytes(bitstring()) -> gleam@option:option(binary()).
content_type_from_bytes(Body) ->
_pipe = mimetype:detect_strict(Body),
_pipe@1 = gleam@option:from_result(_pipe),
gleam@option:map(_pipe@1, fun mimetype:essence_of/1).
-file("src/multipartkit/infer.gleam", 67).
?DOC(
" Inferer backed by the built-in `content_type_from_filename` and\n"
" `content_type_from_bytes` helpers (which delegate to\n"
" `nao1215/mimetype`).\n"
"\n"
" Pass this to `form.add_file_auto_with` to get content-type inference\n"
" for well-known extensions and magic-byte signatures without writing\n"
" the `mimetype` wiring yourself:\n"
"\n"
" ```gleam\n"
" form.add_file_auto_with(my_form, \"upload\", \"photo.png\", bytes, infer.builtin_inferer())\n"
" // -> the part's Content-Type is image/png\n"
" ```\n"
).
-spec builtin_inferer() -> inferer().
builtin_inferer() ->
{inferer, fun content_type_from_filename/1, fun content_type_from_bytes/1}.