Current section

Files

Jump to
gleam_erlang src gleam_erlang_ffi.erl
Raw

src/gleam_erlang_ffi.erl

-module(gleam_erlang_ffi).
-export([atom_from_dynamic/1, atom_create_from_string/1, atom_to_string/1,
rescue/1, atom_from_string/1, get_line/1, ensure_all_started/1,
sleep/1, sleep_forever/0, read_file/1, write_file/2, delete_file/1]).
-spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}.
atom_from_string(S) ->
try {ok, binary_to_existing_atom(S, utf8)}
catch error:badarg -> {error, atom_not_loaded}
end.
-spec atom_create_from_string(binary()) -> atom().
atom_create_from_string(S) ->
binary_to_atom(S, utf8).
-spec atom_to_string(atom()) -> binary().
atom_to_string(S) ->
atom_to_binary(S, utf8).
% TODO: Improve error type
-spec atom_from_dynamic(any()) -> {ok, atom()} | {error, binary()}.
atom_from_dynamic(Data) when is_atom(Data) ->
{ok, Data};
atom_from_dynamic(Data) ->
{error, {decode_error, <<"Atom">>, gleam@dynamic:classify(Data)}}.
-spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}.
get_line(Prompt) ->
case io:get_line(Prompt) of
eof -> {error, eof};
{error, _} -> {error, no_data};
Data when is_binary(Data) -> {ok, Data};
Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)}
end.
rescue(F) ->
try {ok, F()}
catch
throw:X -> {error, {thrown, X}};
error:X -> {error, {errored, X}};
exit:X -> {error, {exited, X}}
end.
ensure_all_started(Application) ->
case application:ensure_all_started(Application) of
{ok, _} = Ok -> Ok;
{error, {ProblemApp, {"no such file or directory", _}}} ->
{error, {unknown_application, ProblemApp}}
end.
sleep(Microseconds) ->
timer:sleep(Microseconds),
nil.
sleep_forever() ->
timer:sleep(infinity),
nil.
read_file(Filename) ->
case file:read_file(Filename) of
{ok, Bitstring} -> {ok, Bitstring};
{error, Reason} ->
ensure_posix(Reason),
{error, Reason}
end.
write_file(Contents, Filename) ->
case file:write_file(Filename, Contents) of
ok -> {ok, nil};
{error, Reason} ->
ensure_posix(Reason),
{error, Reason}
end.
delete_file(Filename) ->
case file:delete(Filename) of
ok -> {ok, nil};
{error, Reason} ->
ensure_posix(Reason),
{error, Reason}
end.
ensure_posix(Error) ->
IsPosixCode = posix(Error),
if IsPosixCode =:= true -> Error;
true -> error(erlang_error)
end.
posix(Error) ->
lists:member(Error, [eacces, eagain, ebadf, ebadmsg, ebusy, edeadlk,
edeadlock, edquot, eexist, efault, efbig, eftype, eintr,
einval, eio, eisdir, eloop, emfile, emlink, emultihop,
enametoolong, enfile, enobufs, enodev, enolck, enolink,
enoent, enomem, enospc, enosr, enostr, enosys, enotblk,
enotdir, enotsup, enxio, eopnotsupp, eoverflow, eperm,
epipe, erange, erofs, espipe , esrch , estale, etxtbsy,
exdev]).