Current section
Files
Jump to
Current section
Files
src/dream_test_file_ffi.erl
-module(dream_test_file_ffi).
-export([read_file/1, write_file/2, delete_file/1, delete_files_matching/2]).
%% Read a file and return its contents as a binary string.
%% Returns {ok, Binary} on success, {error, FileError} on failure.
read_file(Path) ->
case file:read_file(Path) of
{ok, Binary} -> {ok, Binary};
{error, Reason} -> {error, make_error(Path, Reason)}
end.
%% Write content to a file, creating parent directories if needed.
%% Returns {ok, nil} on success, {error, FileError} on failure.
write_file(Path, Content) ->
case filelib:ensure_dir(Path) of
ok ->
write_file_content(Path, Content);
{error, Reason} ->
{error, make_error(Path, Reason)}
end.
write_file_content(Path, Content) ->
case file:write_file(Path, Content) of
ok -> {ok, nil};
{error, Reason} -> {error, make_error(Path, Reason)}
end.
%% Delete a file. Returns {ok, nil} on success or if file doesn't exist.
%% Returns {error, FileError} on other failures.
delete_file(Path) ->
case file:delete(Path) of
ok -> {ok, nil};
{error, enoent} -> {ok, nil};
{error, Reason} -> {error, make_error(Path, Reason)}
end.
%% Delete all files in a directory matching the given extension.
%% Returns {ok, Count} where Count is the number of files deleted.
%% Returns {error, FileError} if directory access fails.
delete_files_matching(Directory, Extension) ->
DirStr = binary_to_list(Directory),
ExtStr = binary_to_list(Extension),
Pattern = filename:join(DirStr, "*" ++ ExtStr),
try
Files = filelib:wildcard(Pattern),
Count = delete_files_loop(Files, 0),
{ok, Count}
catch
_:Reason ->
{error, make_error(Directory, Reason)}
end.
delete_files_loop([], Count) ->
Count;
delete_files_loop([File | Rest], Count) ->
case file:delete(File) of
ok -> delete_files_loop(Rest, Count + 1);
{error, _} -> delete_files_loop(Rest, Count)
end.
%% Convert Erlang file error reasons to Gleam FileError type.
%% These constructors must match the Gleam type definition exactly.
make_error(Path, enoent) ->
{not_found, Path};
make_error(Path, eacces) ->
{permission_denied, Path};
make_error(Path, eisdir) ->
{is_directory, Path};
make_error(Path, enospc) ->
{no_space, Path};
make_error(Path, Reason) when is_atom(Reason) ->
{file_system_error, Path, atom_to_binary(Reason, utf8)};
make_error(Path, Reason) ->
{file_system_error, Path, list_to_binary(io_lib:format("~p", [Reason]))}.