Current section

Files

Jump to
possum src possum@handle.erl
Raw

src/possum@handle.erl

-module(possum@handle).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/possum/handle.gleam").
-export([to_string/1, parse/1]).
-export_type([parse_error/0, handle/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(
" DIDs are the long-term persistent identifiers for accounts in atproto,\n"
" but they can be opaque and unfriendly for human use. Handles are mutable\n"
" and human-friendly account usernames, in the form of a DNS hostname.\n"
" For example, \"user.example.com\".\n"
"\n"
" Documentation: [Handle](https://atproto.com/specs/handle)\n"
).
-type parse_error() :: {invalid_regex_pattern, binary()} |
{invalid_syntax, binary()} |
{disallowed_top_level_domain, binary()}.
-opaque handle() :: {handle, binary()}.
-file("src/possum/handle.gleam", 56).
?DOC(
" Convert a handle into a String\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" import possum/handle\n"
"\n"
" let string = \"gleam.run\"\n"
" let assert Ok(handle) = handle.parse(string)\n"
"\n"
" assert handle.to_string(handle) == \"gleam.run\"\n"
" ```\n"
).
-spec to_string(handle()) -> binary().
to_string(Handle) ->
erlang:element(2, Handle).
-file("src/possum/handle.gleam", 86).
-spec check_invalid_domains(binary()) -> {ok, binary()} | {error, parse_error()}.
check_invalid_domains(Value) ->
Disallowed_domains = [<<".alt"/utf8>>,
<<".arpa"/utf8>>,
<<".internal"/utf8>>,
<<".invalid"/utf8>>,
<<".local"/utf8>>,
<<".localhost"/utf8>>,
<<".onion"/utf8>>],
gleam@list:try_fold(
Disallowed_domains,
Value,
fun(Acc, Domain) -> case gleam_stdlib:string_ends_with(Acc, Domain) of
true ->
{error, {disallowed_top_level_domain, Domain}};
false ->
{ok, Acc}
end end
).
-file("src/possum/handle.gleam", 71).
?DOC(
" Parse a string into a valid `Handle` type\n"
" If the value is not a valid string then an error is returned.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" import possum/handle\n"
"\n"
" let string = \"gleam.run\"\n"
" let assert Ok(handle) = handle.parse(string)\n"
" ```\n"
).
-spec parse(binary()) -> {ok, handle()} | {error, parse_error()}.
parse(Content) ->
gleam@result:'try'(
begin
_pipe = gleam@regexp:from_string(
<<"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$"/utf8>>
),
gleam@result:replace_error(
_pipe,
{invalid_regex_pattern,
<<"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$"/utf8>>}
)
end,
fun(With) ->
gleam@result:'try'(case gleam@regexp:check(With, Content) of
true ->
{ok, Content};
false ->
{error, {invalid_syntax, Content}}
end, fun(Value) ->
gleam@result:map(
check_invalid_domains(Value),
fun(Value@1) -> {handle, Value@1} end
)
end)
end
).