-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.