Packages

Gleam bindings for Erlang's built-in DNS resolution modules.

Current section

Files

Jump to
nessie src nessie.erl
Raw

src/nessie.erl

-module(nessie).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([ip_decoder/0, getbyname/3, getbyname_soa/2, getbyname_ipv4/2, getbyname_ipv6/2, getbyname_mx/2, gethostbyaddr/2, lookup_ipv4/3, lookup_ipv6/3, lookup/4, lookup_soa/3, lookup_mx/3, ip_to_string/1, string_to_ip/1]).
-export_type([dns_class/0, resolver_option/0, soa_record/0, error_reason/0, mx_record/0, timeout_/0, hostent/1, ip_address/0, string_record_type/0]).
-type dns_class() :: in | chaos | hs | any.
-type resolver_option() :: {nameservers, list({ip_address(), integer()})} |
{i_net6, boolean()} |
{recurse, boolean()} |
{retry, integer()} |
{timeout_millis, integer()} |
{nxdomain_reply, boolean()}.
-type soa_record() :: {soa_record,
binary(),
binary(),
integer(),
integer(),
integer(),
integer(),
integer()}.
-type error_reason() :: formerr |
qfmterr |
servfail |
nxdomain |
notimp |
refused |
badvers |
timeout_err |
{other, binary()}.
-type mx_record() :: {mx_record, integer(), binary()}.
-type timeout_() :: {timeout, integer()} | infinity.
-type hostent(FWQ) :: {hostent,
binary(),
list(binary()),
binary(),
integer(),
list(FWQ)}.
-type ip_address() :: {ipv4, {integer(), integer(), integer(), integer()}} |
{ipv6,
{integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()}}.
-type string_record_type() :: cname | txt | ns.
-spec ip_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, ip_address()} |
{error, list(gleam@dynamic:decode_error())}).
ip_decoder() ->
fun(Value) -> _pipe = Value,
_pipe@1 = (gleam@dynamic:tuple4(
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1
))(_pipe),
_pipe@2 = gleam@result:map(_pipe@1, fun(Field@0) -> {ipv4, Field@0} end),
gleam@result:lazy_or(_pipe@2, fun() -> _pipe@3 = Value,
_pipe@4 = (gleam@dynamic:decode8(
fun(I1, I2, I3, I4, I5, I6, I7, I8) ->
{I1, I2, I3, I4, I5, I6, I7, I8}
end,
gleam@dynamic:element(0, fun gleam@dynamic:int/1),
gleam@dynamic:element(1, fun gleam@dynamic:int/1),
gleam@dynamic:element(2, fun gleam@dynamic:int/1),
gleam@dynamic:element(3, fun gleam@dynamic:int/1),
gleam@dynamic:element(4, fun gleam@dynamic:int/1),
gleam@dynamic:element(5, fun gleam@dynamic:int/1),
gleam@dynamic:element(6, fun gleam@dynamic:int/1),
gleam@dynamic:element(7, fun gleam@dynamic:int/1)
))(_pipe@3),
gleam@result:map(_pipe@4, fun(Field@0) -> {ipv6, Field@0} end) end) end.
-spec to_erl_resolver_option(resolver_option()) -> {gleam@erlang@atom:atom_(),
gleam@dynamic:dynamic_()}.
to_erl_resolver_option(Option) ->
{Opt_name, Opt_value} = case Option of
{i_net6, Inet6} ->
{<<"inet6"/utf8>>, gleam@dynamic:from(Inet6)};
{recurse, Recurse} ->
{<<"recurse"/utf8>>, gleam@dynamic:from(Recurse)};
{retry, Retry} ->
{<<"retry"/utf8>>, gleam@dynamic:from(Retry)};
{timeout_millis, Timeout} ->
{<<"timeout"/utf8>>, gleam@dynamic:from(Timeout)};
{nxdomain_reply, Nxdomain_reply} ->
{<<"nxdomain_reply"/utf8>>, gleam@dynamic:from(Nxdomain_reply)};
{nameservers, Nameservers} ->
Erl_nameservers = gleam@list:map(
Nameservers,
fun(Ip_port) ->
{Ip, Port} = Ip_port,
Ip@3 = case Ip of
{ipv4, Ip@1} ->
gleam@dynamic:from(Ip@1);
{ipv6, Ip@2} ->
gleam@dynamic:from(Ip@2)
end,
{Ip@3, Port}
end
),
{<<"nameservers"/utf8>>, gleam@dynamic:from(Erl_nameservers)}
end,
{erlang:binary_to_atom(Opt_name), Opt_value}.
-spec to_dns_err(gleam@erlang@atom:atom_()) -> error_reason().
to_dns_err(E) ->
E@1 = erlang:atom_to_binary(E),
case E@1 of
<<"formerr"/utf8>> ->
formerr;
<<"qfmterror"/utf8>> ->
qfmterr;
<<"servfail"/utf8>> ->
servfail;
<<"nxdomain"/utf8>> ->
nxdomain;
<<"notimp"/utf8>> ->
notimp;
<<"refused"/utf8>> ->
refused;
<<"badvers"/utf8>> ->
badvers;
<<"timeout"/utf8>> ->
timeout_err;
_ ->
{other, E@1}
end.
-spec from_dns_name(gleam@dynamic:dynamic_()) -> binary().
from_dns_name(Dyn) ->
Atom_from_dynamic = fun() -> _pipe = Dyn,
_pipe@1 = gleam_erlang_ffi:atom_from_dynamic(_pipe),
gleam@result:map(_pipe@1, fun erlang:atom_to_binary/1) end,
_pipe@2 = Dyn,
_pipe@3 = nessie_inet_res_ffi:charlist_from_dynamic(_pipe@2),
_pipe@4 = gleam@result:map(_pipe@3, fun unicode:characters_to_binary/1),
_pipe@5 = gleam@result:lazy_or(_pipe@4, Atom_from_dynamic),
gleam@result:unwrap(_pipe@5, <<""/utf8>>).
-spec to_hostent(
{gleam@erlang@atom:atom_(),
gleam@dynamic:dynamic_(),
list(gleam@dynamic:dynamic_()),
gleam@erlang@atom:atom_(),
integer(),
list(FYB)},
fun((FYB) -> FYD)
) -> hostent(FYD).
to_hostent(Erl_hostent, Addr_list_transform) ->
{_, Name, Aliases, Addrtype, Length, Addr_list} = Erl_hostent,
Gleam_aliases = gleam@list:map(Aliases, fun from_dns_name/1),
{hostent,
from_dns_name(Name),
Gleam_aliases,
erlang:atom_to_binary(Addrtype),
Length,
gleam@list:map(Addr_list, Addr_list_transform)}.
-spec to_mx({integer(), gleam@dynamic:dynamic_()}) -> mx_record().
to_mx(Erl_mx) ->
{Priority, Exchange} = Erl_mx,
{mx_record, Priority, from_dns_name(Exchange)}.
-spec to_soa(
{gleam@dynamic:dynamic_(),
gleam@dynamic:dynamic_(),
integer(),
integer(),
integer(),
integer(),
integer()}
) -> soa_record().
to_soa(Erl_soa) ->
{Mname, Rname, Serial, Refresh, Retry, Expire, Minimum} = Erl_soa,
{soa_record,
from_dns_name(Mname),
from_dns_name(Rname),
Serial,
Refresh,
Retry,
Expire,
Minimum}.
-spec getbyname(binary(), string_record_type(), timeout_()) -> {ok,
hostent(binary())} |
{error, error_reason()}.
getbyname(Name, Srt, Timeout) ->
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:getbyname(_pipe, Srt, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) ->
to_hostent(_capture, fun unicode:characters_to_binary/1)
end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec getbyname_soa(binary(), timeout_()) -> {ok, hostent(soa_record())} |
{error, error_reason()}.
getbyname_soa(Name, Timeout) ->
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:getbyname_soa(_pipe, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) -> to_hostent(_capture, fun to_soa/1) end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec getbyname_ipv4(binary(), timeout_()) -> {ok,
hostent({integer(), integer(), integer(), integer()})} |
{error, error_reason()}.
getbyname_ipv4(Name, Timeout) ->
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:getbyname_ipv4(_pipe, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) -> to_hostent(_capture, fun gleam@function:identity/1) end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec getbyname_ipv6(binary(), timeout_()) -> {ok,
hostent({integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()})} |
{error, error_reason()}.
getbyname_ipv6(Name, Timeout) ->
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:getbyname_ipv6(_pipe, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) -> to_hostent(_capture, fun gleam@function:identity/1) end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec getbyname_mx(binary(), timeout_()) -> {ok, hostent(mx_record())} |
{error, error_reason()}.
getbyname_mx(Name, Timeout) ->
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:getbyname_mx(_pipe, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) -> to_hostent(_capture, fun to_mx/1) end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec gethostbyaddr(ip_address(), timeout_()) -> {ok, hostent(binary())} |
{error, error_reason()}.
gethostbyaddr(Address, Timeout) ->
_pipe = Address,
_pipe@1 = nessie_inet_res_ffi:gethostbyaddr(_pipe, Timeout),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(_capture) ->
to_hostent(_capture, fun unicode:characters_to_binary/1)
end
),
gleam@result:map_error(_pipe@2, fun to_dns_err/1).
-spec lookup_ipv4(binary(), dns_class(), list(resolver_option())) -> list({integer(),
integer(),
integer(),
integer()}).
lookup_ipv4(Name, Class, Options) ->
Erl_options = gleam@list:map(Options, fun to_erl_resolver_option/1),
nessie_inet_res_ffi:lookup_ipv4(Name, Class, Erl_options).
-spec lookup_ipv6(binary(), dns_class(), list(resolver_option())) -> list({integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()}).
lookup_ipv6(Name, Class, Options) ->
Erl_options = gleam@list:map(Options, fun to_erl_resolver_option/1),
nessie_inet_res_ffi:lookup_ipv6(Name, Class, Erl_options).
-spec lookup(
binary(),
dns_class(),
string_record_type(),
list(resolver_option())
) -> list(binary()).
lookup(Name, Class, Srt, Options) ->
Erl_options = gleam@list:map(Options, fun to_erl_resolver_option/1),
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:lookup(_pipe, Class, Srt, Erl_options),
gleam@list:map(_pipe@1, fun unicode:characters_to_binary/1).
-spec lookup_soa(binary(), dns_class(), list(resolver_option())) -> list(soa_record()).
lookup_soa(Name, Class, Options) ->
Erl_options = gleam@list:map(Options, fun to_erl_resolver_option/1),
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:lookup_soa(_pipe, Class, Erl_options),
gleam@list:map(_pipe@1, fun to_soa/1).
-spec lookup_mx(binary(), dns_class(), list(resolver_option())) -> list(mx_record()).
lookup_mx(Name, Class, Options) ->
Erl_options = gleam@list:map(Options, fun to_erl_resolver_option/1),
_pipe = Name,
_pipe@1 = nessie_inet_res_ffi:lookup_mx(_pipe, Class, Erl_options),
gleam@list:map(_pipe@1, fun to_mx/1).
-spec ip_to_string(ip_address()) -> {ok, binary()} | {error, binary()}.
ip_to_string(Ip_addr) ->
_pipe = Ip_addr,
_pipe@1 = nessie_inet_ffi:ntoa(_pipe),
_pipe@2 = gleam@result:map(_pipe@1, fun unicode:characters_to_binary/1),
gleam@result:map_error(_pipe@2, fun erlang:atom_to_binary/1).
-spec string_to_ip(binary()) -> {ok, ip_address()} | {error, binary()}.
string_to_ip(Ip_addr) ->
_pipe = Ip_addr,
_pipe@1 = nessie_inet_ffi:parse_address(_pipe),
_pipe@2 = gleam@result:map_error(_pipe@1, fun erlang:atom_to_binary/1),
_pipe@8 = gleam@result:map(_pipe@2, fun(Dyn) -> _pipe@3 = Dyn,
_pipe@4 = (gleam@dynamic:tuple4(
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1,
fun gleam@dynamic:int/1
))(_pipe@3),
_pipe@5 = gleam@result:map(
_pipe@4,
fun(Field@0) -> {ipv4, Field@0} end
),
_pipe@7 = gleam@result:'or'(
_pipe@5,
begin
_pipe@6 = Dyn,
(ip_decoder())(_pipe@6)
end
),
gleam@result:replace_error(_pipe@7, <<"decode_error"/utf8>>) end),
gleam@result:flatten(_pipe@8).