Skip to main content

src/internal@encoder@idna.erl

-module(internal@encoder@idna).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/internal/encoder/idna.gleam").
-export([encode_domain/2, encode_email_address/2]).

-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(
    " Encode domain parts using Internationalized Domain Names for Applications\n"
    " (IDNA).\n"
    "\n"
    " See the following link for reference:\n"
    " - <https://www.rfc-editor.org/rfc/rfc5890>\n"
).

-file("src/internal/encoder/idna.gleam", 37).
-spec encode_domain(binary(), internal@encoder@encoding:encoding_mode()) -> {ok,
        binary()} |
    {error, internal@encoder@encoding:encoder_error()}.
encode_domain(Domain, Mode) ->
    case Mode of
        ascii ->
            _pipe = glidna:to_ascii(Domain),
            gleam@result:replace_error(_pipe, {invalid_domain, Domain});

        utf8 ->
            {ok, Domain}
    end.

-file("src/internal/encoder/idna.gleam", 18).
?DOC(
    " Encode an email address according to IDNA encoding.\n"
    "\n"
    " It leaves the local part as is, and only encodes the domain part.\n"
    " If `mode` is `Utf8`, it will also leave the domain part as is.\n"
).
-spec encode_email_address(binary(), internal@encoder@encoding:encoding_mode()) -> {ok,
        binary()} |
    {error, internal@encoder@encoding:encoder_error()}.
encode_email_address(Address, Mode) ->
    _pipe = Address,
    _pipe@1 = gleam@string:reverse(_pipe),
    _pipe@2 = gleam@string:split_once(_pipe@1, <<"@"/utf8>>),
    _pipe@3 = gleam@result:replace_error(
        _pipe@2,
        {invalid_email_address, Address}
    ),
    _pipe@7 = gleam@result:'try'(
        _pipe@3,
        fun(Parts) ->
            {Domain, Local} = Parts,
            _pipe@4 = Domain,
            _pipe@5 = gleam@string:reverse(_pipe@4),
            _pipe@6 = encode_domain(_pipe@5, Mode),
            gleam@result:map(
                _pipe@6,
                fun(Domain@1) ->
                    <<<<(gleam@string:reverse(Local))/binary, "@"/utf8>>/binary,
                        Domain@1/binary>>
                end
            )
        end
    ),
    gleam@result:replace_error(_pipe@7, {invalid_email_address, Address}).