-module(fswalk). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([builder/0, with_path/2, with_filter/2, walk/1, each/2, map/2, fold/3]). -export_type([non/0, som/0, walk_builder/2, stat/0, entry/0]). -opaque non() :: any(). -opaque som() :: any(). -opaque walk_builder(FYT, FYU) :: {walk_builder, gleam@option:option(fun((entry()) -> boolean())), gleam@option:option(binary())} | {gleam_phantom, FYT, FYU}. -type stat() :: {stat, boolean()}. -type entry() :: {entry, binary(), stat()}. -spec builder() -> walk_builder(non(), non()). builder() -> {walk_builder, none, none}. -spec with_path(walk_builder(FYX, any()), binary()) -> walk_builder(FYX, som()). with_path(Builder, Path) -> {walk_builder, erlang:element(2, Builder), {some, Path}}. -spec with_filter(walk_builder(any(), FZE), fun((entry()) -> boolean())) -> walk_builder(som(), FZE). with_filter(Builder, Filter) -> {walk_builder, {some, Filter}, erlang:element(3, Builder)}. -spec to_entry(binary()) -> entry(). to_entry(Filename) -> {entry, Filename, {stat, simplifile:is_directory(Filename)}}. -spec path_to_entry(gleam_community@path:path()) -> entry(). path_to_entry(Pth) -> to_entry(gleam_community@path:to_string(Pth)). -spec ok(FZN) -> {ok, FZN} | {error, any()}. ok(X) -> {ok, X}. -spec walk_path(gleam_community@path:path(), fun((entry()) -> boolean())) -> gleam@iterator:iterator({ok, entry()} | {error, simplifile:file_error()}). walk_path(Pth, Filter) -> _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} -> {Allpaths, Folderpaths} = gleam@list:fold( Filenames, {[], []}, fun(Acc, F) -> Filepath = gleam_community@path:append_string( Pth, F ), Next_allpaths = [Filepath | erlang:element(1, Acc)], case simplifile:is_directory( gleam_community@path:to_string(Filepath) ) of true -> {Next_allpaths, [Filepath | erlang:element(2, Acc)]}; false -> {Next_allpaths, erlang:element(2, Acc)} end end ), Ok_entries = begin _pipe@1 = Allpaths, _pipe@2 = gleam@list:map(_pipe@1, fun path_to_entry/1), _pipe@3 = gleam@list:filter( _pipe@2, fun(Entry) -> Filter(Entry) end ), _pipe@4 = gleam@list:map(_pipe@3, fun ok/1), gleam@iterator:from_list(_pipe@4) end, gleam@iterator:concat( [Ok_entries | gleam@list:map( Folderpaths, fun(Fp) -> walk_path(Fp, Filter) end )] ) end end). -spec walk(walk_builder(any(), som())) -> gleam@iterator:iterator({ok, entry()} | {error, simplifile:file_error()}). walk(Builder) -> {walk_builder, 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 => 50}) end, Filter = case Filter_opt of {some, F} -> F; _ -> fun(_) -> true end end, walk_path(gleam_community@path:from_string(Root_path), Filter). -spec each(gleam@iterator:iterator(GCM), fun((GCM) -> any())) -> nil. each(It, Fun) -> _pipe = It, gleam@iterator:each(_pipe, Fun). -spec map(gleam@iterator:iterator(GCO), fun((GCO) -> GCP)) -> gleam@iterator:iterator(GCP). map(It, Fun) -> _pipe = It, gleam@iterator:map(_pipe, Fun). -spec fold(gleam@iterator:iterator(GCQ), FZZ, fun((FZZ, GCQ) -> FZZ)) -> FZZ. fold(It, Init, Fun) -> _pipe = It, gleam@iterator:fold(_pipe, Init, Fun).