Current section
Files
Jump to
Current section
Files
src/filespy.erl
-module(filespy).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/0, add_dir/2, add_dirs/2, set_actor_handler/2, set_initial_state/2, set_handler/2, set_initializer/2, selector/0, spec/1, start/1]).
-export_type([no_directories/0, has_directories/0, no_handler/0, has_handler/0, no_initial_state/0, has_initial_state/0, event/0, change/1, builder/5]).
-type no_directories() :: any().
-type has_directories() :: any().
-type no_handler() :: any().
-type has_handler() :: any().
-type no_initial_state() :: any().
-type has_initial_state() :: any().
-type event() :: created |
modified |
closed |
deleted |
renamed |
attribute |
{unknown, gleam@erlang@atom:atom_()}.
-type change(HEN) :: {change, binary(), list(event())} | {custom, HEN}.
-opaque builder(HEO, HEP, HEQ, HER, HES) :: {builder,
list(binary()),
gleam@option:option(fun((change(HES), HEO) -> gleam@otp@actor:next(change(HES), HEO))),
gleam@option:option(fun(() -> HEO))} |
{gleam_phantom, HEP, HEQ, HER}.
-spec new() -> builder(any(), no_directories(), no_handler(), no_initial_state(), nil).
new() ->
{builder, [], none, none}.
-spec add_dir(builder(HFH, any(), HFJ, HFK, HFL), binary()) -> builder(HFH, has_directories(), HFJ, HFK, HFL).
add_dir(Builder, Directory) ->
{builder,
[Directory | erlang:element(2, Builder)],
erlang:element(3, Builder),
erlang:element(4, Builder)}.
-spec add_dirs(builder(HFW, any(), HFY, HFZ, HGA), list(binary())) -> builder(HFW, has_directories(), HFY, HFZ, HGA).
add_dirs(Builder, Directories) ->
{builder,
lists:append(Directories, erlang:element(2, Builder)),
erlang:element(3, Builder),
erlang:element(4, Builder)}.
-spec set_actor_handler(
builder(HGY, HGZ, no_handler(), HHA, HHB),
fun((change(HHB), HGY) -> gleam@otp@actor:next(change(HHB), HGY))
) -> builder(HGY, HGZ, has_handler(), HHA, HHB).
set_actor_handler(Builder, Handler) ->
{builder,
erlang:element(2, Builder),
{some, Handler},
erlang:element(4, Builder)}.
-spec set_initial_state(builder(HHO, HHP, HHQ, no_initial_state(), HHR), HHO) -> builder(HHO, HHP, HHQ, has_initial_state(), HHR).
set_initial_state(Builder, State) ->
{builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
{some, fun() -> State end}}.
-spec set_handler(
builder(nil, HGM, no_handler(), no_initial_state(), HGN),
fun((binary(), event()) -> nil)
) -> builder(nil, HGM, has_handler(), has_initial_state(), HGN).
set_handler(Builder, Handler) ->
Wrapped_handler = fun(Event, _) ->
case Event of
{change, Path, Events} ->
gleam@list:each(Events, fun(Ev) -> Handler(Path, Ev) end);
_ ->
nil
end,
gleam@otp@actor:continue(nil)
end,
_pipe = Builder,
_pipe@1 = set_actor_handler(_pipe, Wrapped_handler),
set_initial_state(_pipe@1, nil).
-spec set_initializer(
builder(HIC, HID, HIE, no_initial_state(), HIF),
fun(() -> HIC)
) -> builder(HIC, HID, HIE, has_initial_state(), HIF).
set_initializer(Builder, Initializer) ->
{builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
{some, Initializer}}.
-spec to_event(gleam@dynamic:dynamic_()) -> {ok, event()} |
{error, list(gleam@dynamic:decode_error())}.
to_event(From) ->
gleam@result:'try'(
gleam_erlang_ffi:atom_from_dynamic(From),
fun(Event) ->
Created = erlang:binary_to_atom(<<"created"/utf8>>),
Deleted = erlang:binary_to_atom(<<"deleted"/utf8>>),
Modified = erlang:binary_to_atom(<<"modified"/utf8>>),
Closed = erlang:binary_to_atom(<<"closed"/utf8>>),
Renamed = erlang:binary_to_atom(<<"renamed"/utf8>>),
Attrib = erlang:binary_to_atom(<<"attribute"/utf8>>),
Removed = erlang:binary_to_atom(<<"removed"/utf8>>),
case Event of
Ev when Ev =:= Created ->
{ok, created};
Ev@1 when Ev@1 =:= Deleted ->
{ok, deleted};
Ev@2 when Ev@2 =:= Modified ->
{ok, modified};
Ev@3 when Ev@3 =:= Closed ->
{ok, closed};
Ev@4 when Ev@4 =:= Renamed ->
{ok, renamed};
Ev@5 when Ev@5 =:= Removed ->
{ok, deleted};
Ev@6 when Ev@6 =:= Attrib ->
{ok, attribute};
Other ->
{ok, {unknown, Other}}
end
end
).
-spec selector() -> gleam@erlang@process:selector(change(any())).
selector() ->
Change_selector = gleam@dynamic:tuple3(
fun gleam@dynamic:dynamic/1,
fun gleam@dynamic:dynamic/1,
gleam@dynamic:tuple2(fun(L) -> _pipe = filespy_ffi:identity(L),
_pipe@1 = unicode:characters_to_binary(_pipe),
{ok, _pipe@1} end, gleam@dynamic:list(fun to_event/1))
),
_pipe@2 = gleam_erlang_ffi:new_selector(),
gleam@erlang@process:selecting_anything(
_pipe@2,
fun(Event) -> case Change_selector(Event) of
{ok, {_, _, {Path, Events}}} ->
{change, Path, Events};
_ ->
{change, <<""/utf8>>, []}
end end
).
-spec spec(
builder(HIW, has_directories(), has_handler(), has_initial_state(), HIX)
) -> gleam@otp@actor:spec(HIW, change(HIX)).
spec(Builder) ->
_assert_subject = erlang:element(3, Builder),
{some, Handler} = case _assert_subject of
{some, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"filespy"/utf8>>,
function => <<"spec"/utf8>>,
line => 256})
end,
_assert_subject@1 = erlang:element(4, Builder),
{some, Initializer} = case _assert_subject@1 of
{some, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"filespy"/utf8>>,
function => <<"spec"/utf8>>,
line => 257})
end,
{spec,
fun() ->
{Oks, Errs} = begin
_pipe = erlang:element(2, Builder),
_pipe@2 = gleam@list:map(
_pipe,
fun(Dir) ->
Atom = erlang:binary_to_atom(
<<"fs_watcher"/utf8, Dir/binary>>
),
_pipe@1 = fs:start_link(Atom, Dir),
gleam@result:map(_pipe@1, fun(Pid) -> {Pid, Atom} end)
end
),
gleam@result:partition(_pipe@2)
end,
case Errs of
[] ->
_pipe@3 = Oks,
gleam@list:each(
_pipe@3,
fun(Res) ->
{_, Atom@1} = Res,
fs:subscribe(Atom@1)
end
),
{ready, Initializer(), selector()};
Errs@1 ->
gleam@list:each(
Oks,
fun(Res@1) ->
{Pid@1, _} = Res@1,
gleam@erlang@process:kill(Pid@1)
end
),
{failed,
<<"Failed to start watcher: "/utf8,
(gleam@string:inspect(Errs@1))/binary>>}
end
end,
5000,
Handler}.
-spec start(
builder(any(), has_directories(), has_handler(), has_initial_state(), HJH)
) -> {ok, gleam@erlang@process:subject(change(HJH))} |
{error, gleam@otp@actor:start_error()}.
start(Builder) ->
_pipe = spec(Builder),
gleam@otp@actor:start_spec(_pipe).