-module(sendr@message@attachment).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/sendr/message/attachment.gleam").
-export([set_filename_utf8/3, set_filename/3, from_data/2, from_file/1, set_content_id/2, set_content_type/2]).
-export_type([attachment/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.
?MODULEDOC(
" This module provides a lax representation of an attachment as defined in\n"
" [RFC 2045](https://tools.ietf.org/html/rfc2045).\n"
"\n"
" It does not enforce any of the rules and requirements of the RFC. Since we\n"
" do not know what transformations the Mail Submission Agent will perform and\n"
" what the Mail Submission Agent is capable of handling.\n"
).
-type attachment() :: {attached_attachment,
binary(),
binary(),
binary(),
bitstring()} |
{inlined_attachment, binary(), binary(), binary(), bitstring(), binary()}.
-file("src/sendr/message/attachment.gleam", 165).
-spec guess_content_type(binary()) -> binary().
guess_content_type(Path) ->
_pipe = filepath:extension(Path),
_pipe@1 = gleam@result:map(_pipe, fun marceau:extension_to_mime_type/1),
gleam@result:unwrap(_pipe@1, <<"application/octet-stream"/utf8>>).
-file("src/sendr/message/attachment.gleam", 145).
?DOC(
" Set the `filename_utf8` on the attachment (for UTF-8 filenames).\n"
" Optionally also updates the content type.\n"
"\n"
" The filename is used to suggest a name for the attachment when it is saved\n"
" by the recipient. This is particularly useful for attachments that are\n"
" intended to be downloaded or saved.\n"
).
-spec set_filename_utf8(attachment(), binary(), boolean()) -> attachment().
set_filename_utf8(Attachment, Path, Update) ->
Filename_utf8 = filepath:base_name(Path),
Content_type = case Update of
false ->
erlang:element(2, Attachment);
true ->
guess_content_type(Filename_utf8)
end,
case Attachment of
{attached_attachment, _, _, _, _} ->
{attached_attachment,
Content_type,
erlang:element(3, Attachment),
Filename_utf8,
erlang:element(5, Attachment)};
{inlined_attachment, _, _, _, _, _} ->
{inlined_attachment,
Content_type,
erlang:element(3, Attachment),
Filename_utf8,
erlang:element(5, Attachment),
erlang:element(6, Attachment)}
end.
-file("src/sendr/message/attachment.gleam", 119).
?DOC(
" Set the `filename` on the attachment (for ASCII filenames).\n"
" Optionally also updates the content type.\n"
"\n"
" The filename is used to suggest a name for the attachment when it is saved\n"
" by the recipient. This is particularly useful for attachments that are\n"
" intended to be downloaded or saved.\n"
).
-spec set_filename(attachment(), binary(), boolean()) -> attachment().
set_filename(Attachment, Path, Update) ->
Filename = filepath:base_name(Path),
Content_type = case Update of
false ->
erlang:element(2, Attachment);
true ->
guess_content_type(Filename)
end,
case Attachment of
{attached_attachment, _, _, _, _} ->
{attached_attachment,
Content_type,
Filename,
erlang:element(4, Attachment),
erlang:element(5, Attachment)};
{inlined_attachment, _, _, _, _, _} ->
{inlined_attachment,
Content_type,
Filename,
erlang:element(4, Attachment),
erlang:element(5, Attachment),
erlang:element(6, Attachment)}
end.
-file("src/sendr/message/attachment.gleam", 171).
-spec is_ascii_only(binary()) -> boolean().
is_ascii_only(Value) ->
_pipe = Value,
_pipe@1 = gleam@string:split(_pipe, <<""/utf8>>),
gleam@list:all(
_pipe@1,
fun(Char) -> gleam@string:compare(Char, <<"\x{80}"/utf8>>) =:= lt end
).
-file("src/sendr/message/attachment.gleam", 41).
?DOC(
" Create a new attachment from raw data.\n"
"\n"
" This function allows creating an attachment directly from binary data. It is\n"
" useful when the attachment data is already available in memory.\n"
).
-spec from_data(binary(), bitstring()) -> attachment().
from_data(Path, Data) ->
Attachment = {attached_attachment,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
Data},
Filename = filepath:base_name(Path),
case is_ascii_only(Filename) of
true ->
set_filename(Attachment, Filename, true);
false ->
set_filename_utf8(Attachment, Filename, true)
end.
-file("src/sendr/message/attachment.gleam", 64).
?DOC(
" Create a new attachment from a file.\n"
"\n"
" This function reads the file, determines its content type based on its\n"
" extension, and creates an attachment with the file's data. If the content\n"
" type cannot be determined, it defaults to \"application/octet-stream\".\n"
).
-spec from_file(binary()) -> {ok, attachment()} |
{error, simplifile:file_error()}.
from_file(Path) ->
_pipe = simplifile_erl:read_bits(Path),
gleam@result:map(_pipe, fun(_capture) -> from_data(Path, _capture) end).
-file("src/sendr/message/attachment.gleam", 74).
?DOC(
" Set the `content-id` on the attachment.\n"
"\n"
" The content ID is used to uniquely identify the attachment within the\n"
" message. This is particularly useful for referencing the attachment in the\n"
" message body.\n"
).
-spec set_content_id(attachment(), binary()) -> attachment().
set_content_id(Attachment, Content_id) ->
case Content_id of
<<""/utf8>> ->
{attached_attachment,
erlang:element(2, Attachment),
erlang:element(3, Attachment),
erlang:element(4, Attachment),
erlang:element(5, Attachment)};
_ ->
{inlined_attachment,
erlang:element(2, Attachment),
erlang:element(3, Attachment),
erlang:element(4, Attachment),
erlang:element(5, Attachment),
Content_id}
end.
-file("src/sendr/message/attachment.gleam", 101).
?DOC(
" Set the `content-type` on the attachment.\n"
"\n"
" The content type specifies the type of data contained in the attachment.\n"
" This helps the recipient's system to handle the attachment appropriately.\n"
).
-spec set_content_type(attachment(), binary()) -> attachment().
set_content_type(Attachment, Content_type) ->
case Attachment of
{attached_attachment, _, _, _, _} ->
{attached_attachment,
gleam@string:trim(Content_type),
erlang:element(3, Attachment),
erlang:element(4, Attachment),
erlang:element(5, Attachment)};
{inlined_attachment, _, _, _, _, _} ->
{inlined_attachment,
gleam@string:trim(Content_type),
erlang:element(3, Attachment),
erlang:element(4, Attachment),
erlang:element(5, Attachment),
erlang:element(6, Attachment)}
end.