Current section

Files

Jump to
fswalk src fswalk.erl
Raw

src/fswalk.erl

-module(fswalk).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([builder/0, with_path/2, with_entry_filter/2, with_traversal_filter/2, walk/1, each/2, map/2, fold/3, only_dirs/1, only_files/1]).
-export_type([non/0, som/0, walk_builder/3, stat/0, entry/0]).
-opaque non() :: any().
-opaque som() :: any().
-opaque walk_builder(FWI, FWJ, FWK) :: {walk_builder,
gleam@option:option(list(fun((entry()) -> boolean()))),
gleam@option:option(list(fun((entry()) -> boolean()))),
gleam@option:option(binary())} |
{gleam_phantom, FWI, FWJ, FWK}.
-type stat() :: {stat, boolean()}.
-type entry() :: {entry, binary(), stat()}.
-spec builder() -> walk_builder(non(), non(), non()).
builder() ->
{walk_builder, none, none, none}.
-spec with_path(walk_builder(FWO, FWP, any()), binary()) -> walk_builder(FWO, FWP, som()).
with_path(Builder, Path) ->
{walk_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
{some, Path}}.
-spec with_entry_filter(
walk_builder(any(), FWY, FWZ),
fun((entry()) -> boolean())
) -> walk_builder(som(), FWY, FWZ).
with_entry_filter(Builder, Entry_filter) ->
{walk_builder,
{some,
gleam@list:append(
gleam@option:unwrap(erlang:element(2, Builder), []),
[Entry_filter]
)},
erlang:element(3, Builder),
erlang:element(4, Builder)}.
-spec with_traversal_filter(
walk_builder(FXG, any(), FXI),
fun((entry()) -> boolean())
) -> walk_builder(FXG, som(), FXI).
with_traversal_filter(Builder, Traversal_filter) ->
{walk_builder,
erlang:element(2, Builder),
{some,
gleam@list:append(
gleam@option:unwrap(erlang:element(3, Builder), []),
[Traversal_filter]
)},
erlang:element(4, Builder)}.
-spec to_entry(binary()) -> entry().
to_entry(Filename) ->
{entry,
Filename,
{stat,
begin
_pipe = simplifile:verify_is_directory(Filename),
gleam@result:unwrap(_pipe, false)
end}}.
-spec path_to_entry(gleam_community@path:path()) -> entry().
path_to_entry(Pth) ->
to_entry(gleam_community@path:to_string(Pth)).
-spec ok(FXV) -> {ok, FXV} | {error, any()}.
ok(X) ->
{ok, X}.
-spec filter_many(list(GBG), list(fun((GBG) -> boolean()))) -> list(GBG).
filter_many(Xs, Filters) ->
_pipe = Xs,
gleam@list:filter(
_pipe,
fun(Entry) -> gleam@list:all(Filters, fun(F) -> F(Entry) end) end
).
-spec to_ok_iter(list(GBN)) -> gleam@iterator:iterator({ok, GBN} |
{error, any()}).
to_ok_iter(Xs) ->
_pipe = Xs,
_pipe@1 = gleam@list:map(_pipe, fun ok/1),
gleam@iterator:from_list(_pipe@1).
-spec walk_path(
gleam_community@path:path(),
list(fun((entry()) -> boolean())),
list(fun((entry()) -> boolean()))
) -> gleam@iterator:iterator({ok, entry()} | {error, simplifile:file_error()}).
walk_path(Pth, Entry_filters, Traversal_filters) ->
_pipe = gleam@iterator:once(
fun() ->
simplifile:read_directory(gleam_community@path:to_string(Pth))
end
),
gleam@iterator:flat_map(_pipe, fun(Readdir_result) -> case Readdir_result of
{error, X} ->
gleam@iterator:once(fun() -> {error, X} end);
{ok, Filenames} ->
{Filepaths, Folderpaths} = gleam@list:fold(
Filenames,
{[], []},
fun(Acc, F) ->
Filepath = gleam_community@path:append_string(
Pth,
F
),
case begin
_pipe@1 = simplifile:verify_is_directory(
gleam_community@path:to_string(Filepath)
),
gleam@result:unwrap(_pipe@1, false)
end of
true ->
{erlang:element(1, Acc),
[Filepath | erlang:element(2, Acc)]};
false ->
{[Filepath | erlang:element(1, Acc)],
erlang:element(2, Acc)}
end
end
),
Ok_filtered_files = begin
_pipe@2 = Filepaths,
_pipe@3 = gleam@list:map(_pipe@2, fun path_to_entry/1),
_pipe@4 = filter_many(_pipe@3, Entry_filters),
to_ok_iter(_pipe@4)
end,
Candidate_folder_entries = begin
_pipe@5 = Folderpaths,
gleam@list:map(_pipe@5, fun path_to_entry/1)
end,
Ok_filtered_folders = begin
_pipe@6 = Candidate_folder_entries,
_pipe@7 = filter_many(_pipe@6, Entry_filters),
to_ok_iter(_pipe@7)
end,
Traverse_folders = begin
_pipe@8 = Candidate_folder_entries,
filter_many(_pipe@8, Traversal_filters)
end,
gleam@iterator:concat(
[Ok_filtered_files,
Ok_filtered_folders |
gleam@list:map(
Traverse_folders,
fun(Ent) ->
walk_path(
gleam_community@path:from_string(
erlang:element(2, Ent)
),
Entry_filters,
Traversal_filters
)
end
)]
)
end end).
-spec walk(walk_builder(any(), any(), som())) -> gleam@iterator:iterator({ok,
entry()} |
{error, simplifile:file_error()}).
walk(Builder) ->
{walk_builder, Entry_filter_opt, Traversal_filter_opt, Path_opt} = Builder,
{some, Root_path} = case Path_opt of
{some, _} -> Path_opt;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"fswalk"/utf8>>,
function => <<"walk"/utf8>>,
line => 85})
end,
Entry_filters = case Entry_filter_opt of
{some, Xs} ->
Xs;
_ ->
[]
end,
Traversal_filters = case Traversal_filter_opt of
{some, Xs@1} ->
Xs@1;
_ ->
[]
end,
walk_path(
gleam_community@path:from_string(Root_path),
Entry_filters,
Traversal_filters
).
-spec each(gleam@iterator:iterator(GDT), fun((GDT) -> any())) -> nil.
each(It, Fun) ->
_pipe = It,
gleam@iterator:each(_pipe, Fun).
-spec map(gleam@iterator:iterator(GDV), fun((GDV) -> GDW)) -> gleam@iterator:iterator(GDW).
map(It, Fun) ->
_pipe = It,
gleam@iterator:map(_pipe, Fun).
-spec fold(gleam@iterator:iterator(GDX), FYO, fun((FYO, GDX) -> FYO)) -> FYO.
fold(It, Init, Fun) ->
_pipe = It,
gleam@iterator:fold(_pipe, Init, Fun).
-spec only_dirs(entry()) -> boolean().
only_dirs(Ent) ->
erlang:element(2, erlang:element(3, Ent)).
-spec only_files(entry()) -> boolean().
only_files(Ent) ->
not only_dirs(Ent).