Current section
Files
Jump to
Current section
Files
src/glitzer@spinner.erl
-module(glitzer@spinner).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([frames_from_list/1, new_spinner/1, default_spinner/0, bar_up_down_spinner/0, pulsating_spinner/0, bar_left_right_spinner/0, spinning_spinner/0, with_left_text/2, with_frames/2, with_frame_transform/2, with_right_text/2, with_tick_rate/2, prideful_spinner/0, with_finish_text/2, tick/1, tick_by/2, finish/1, print_spinner/1, spin/1]).
-export_type([state/0, frames/0, spinner_style/0]).
-opaque state() :: {state,
frames(),
fun((binary()) -> binary()),
binary(),
binary(),
integer(),
boolean(),
gleam@option:option(repeatedly:repeater(state()))}.
-opaque frames() :: {frames, glearray:array(binary())}.
-opaque spinner_style() :: {spinner_style, integer(), binary(), state()}.
-spec frames_from_list(list(binary())) -> frames().
frames_from_list(Frames) ->
{frames, erlang:list_to_tuple(Frames)}.
-spec new_spinner(frames()) -> spinner_style().
new_spinner(F) ->
{spinner_style,
100,
<<""/utf8>>,
{state,
F,
fun gleam@function:identity/1,
<<""/utf8>>,
<<""/utf8>>,
0,
false,
none}}.
-spec default_spinner() -> spinner_style().
default_spinner() ->
Frames = [<<"|"/utf8>>, <<"/"/utf8>>, <<"-"/utf8>>, <<"\\"/utf8>>],
new_spinner(frames_from_list(Frames)).
-spec bar_up_down_spinner() -> spinner_style().
bar_up_down_spinner() ->
Frames = [<<"\x{2581}"/utf8>>,
<<"\x{2582}"/utf8>>,
<<"\x{2583}"/utf8>>,
<<"\x{2584}"/utf8>>,
<<"\x{2585}"/utf8>>,
<<"\x{2586}"/utf8>>,
<<"\x{2587}"/utf8>>,
<<"\x{2588}"/utf8>>,
<<"\x{2587}"/utf8>>,
<<"\x{2586}"/utf8>>,
<<"\x{2585}"/utf8>>,
<<"\x{2584}"/utf8>>,
<<"\x{2583}"/utf8>>,
<<"\x{2582}"/utf8>>],
new_spinner(frames_from_list(Frames)).
-spec pulsating_spinner() -> spinner_style().
pulsating_spinner() ->
Frames = [<<"\x{2591}"/utf8>>,
<<"\x{2592}"/utf8>>,
<<"\x{2593}"/utf8>>,
<<"\x{2588}"/utf8>>,
<<"\x{2593}"/utf8>>,
<<"\x{2592}"/utf8>>],
new_spinner(frames_from_list(Frames)).
-spec bar_left_right_spinner() -> spinner_style().
bar_left_right_spinner() ->
Frames = [<<"\x{258f}"/utf8>>,
<<"\x{258e}"/utf8>>,
<<"\x{258d}"/utf8>>,
<<"\x{258c}"/utf8>>,
<<"\x{258b}"/utf8>>,
<<"\x{258a}"/utf8>>,
<<"\x{2589}"/utf8>>,
<<"\x{2588}"/utf8>>,
<<"\x{2589}"/utf8>>,
<<"\x{258a}"/utf8>>,
<<"\x{258b}"/utf8>>,
<<"\x{258c}"/utf8>>,
<<"\x{258d}"/utf8>>,
<<"\x{258e}"/utf8>>],
new_spinner(frames_from_list(Frames)).
-spec spinning_spinner() -> spinner_style().
spinning_spinner() ->
Frames = [<<"\x{28fe}"/utf8>>,
<<"\x{28f7}"/utf8>>,
<<"\x{28ef}"/utf8>>,
<<"\x{28df}"/utf8>>,
<<"\x{287f}"/utf8>>,
<<"\x{28bf}"/utf8>>,
<<"\x{28fb}"/utf8>>,
<<"\x{28fd}"/utf8>>],
new_spinner(frames_from_list(Frames)).
-spec with_left_text(spinner_style(), binary()) -> spinner_style().
with_left_text(S, T) ->
S@1 = erlang:setelement(4, S, erlang:setelement(4, erlang:element(4, S), T)),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec with_frames(spinner_style(), frames()) -> spinner_style().
with_frames(S, F) ->
S@1 = erlang:setelement(4, S, erlang:setelement(2, erlang:element(4, S), F)),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec with_frame_transform(spinner_style(), fun((binary()) -> binary())) -> spinner_style().
with_frame_transform(S, Fun) ->
S@1 = erlang:setelement(
4,
S,
erlang:setelement(3, erlang:element(4, S), Fun)
),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec with_right_text(spinner_style(), binary()) -> spinner_style().
with_right_text(S, T) ->
S@1 = erlang:setelement(4, S, erlang:setelement(5, erlang:element(4, S), T)),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec with_tick_rate(spinner_style(), integer()) -> spinner_style().
with_tick_rate(S, Ms) ->
erlang:setelement(2, S, Ms).
-spec prideful_spinner() -> spinner_style().
prideful_spinner() ->
_assert_subject = gleam_community@colour:from_rgb255(0, 0, 0),
{ok, Black} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 129})
end,
_assert_subject@1 = gleam_community@colour:from_rgb255(97, 57, 21),
{ok, Brown} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 130})
end,
_assert_subject@2 = gleam_community@colour:from_rgb255(116, 215, 238),
{ok, Blue} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 131})
end,
_assert_subject@3 = gleam_community@colour:from_rgb255(255, 175, 200),
{ok, Pink} = case _assert_subject@3 of
{ok, _} -> _assert_subject@3;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@3,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 132})
end,
_assert_subject@4 = gleam_community@colour:from_rgb255(255, 255, 255),
{ok, White} = case _assert_subject@4 of
{ok, _} -> _assert_subject@4;
_assert_fail@4 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@4,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 133})
end,
_assert_subject@5 = gleam_community@colour:from_rgb255(115, 41, 130),
{ok, Violet} = case _assert_subject@5 of
{ok, _} -> _assert_subject@5;
_assert_fail@5 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@5,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 134})
end,
_assert_subject@6 = gleam_community@colour:from_rgb255(36, 64, 142),
{ok, Indigo} = case _assert_subject@6 of
{ok, _} -> _assert_subject@6;
_assert_fail@6 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@6,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 135})
end,
_assert_subject@7 = gleam_community@colour:from_rgb255(0, 128, 38),
{ok, Green} = case _assert_subject@7 of
{ok, _} -> _assert_subject@7;
_assert_fail@7 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@7,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 136})
end,
_assert_subject@8 = gleam_community@colour:from_rgb255(255, 237, 0),
{ok, Yellow} = case _assert_subject@8 of
{ok, _} -> _assert_subject@8;
_assert_fail@8 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@8,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 137})
end,
_assert_subject@9 = gleam_community@colour:from_rgb255(255, 140, 0),
{ok, Orange} = case _assert_subject@9 of
{ok, _} -> _assert_subject@9;
_assert_fail@9 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@9,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 138})
end,
_assert_subject@10 = gleam_community@colour:from_rgb255(228, 3, 3),
{ok, Red} = case _assert_subject@10 of
{ok, _} -> _assert_subject@10;
_assert_fail@10 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@10,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 139})
end,
Frames = [gleam_community@ansi:color(<<"\x{2591}"/utf8>>, Black),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Brown),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Blue),
gleam_community@ansi:color(<<"\x{2588}"/utf8>>, Pink),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, White),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Violet),
gleam_community@ansi:color(<<"\x{2591}"/utf8>>, Indigo),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Green),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Yellow),
gleam_community@ansi:color(<<"\x{2588}"/utf8>>, Orange),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Red)],
_pipe = new_spinner(frames_from_list(Frames)),
with_tick_rate(_pipe, 200).
-spec with_finish_text(spinner_style(), binary()) -> spinner_style().
with_finish_text(S, T) ->
erlang:setelement(3, S, T).
-spec tick(spinner_style()) -> spinner_style().
tick(S) ->
S@1 = erlang:setelement(
4,
S,
erlang:setelement(
6,
erlang:element(4, S),
erlang:element(6, erlang:element(4, S)) + 1
)
),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec tick_by(spinner_style(), integer()) -> spinner_style().
tick_by(S, I) ->
S@1 = erlang:setelement(
4,
S,
erlang:setelement(
6,
erlang:element(4, S),
erlang:element(6, erlang:element(4, S)) + I
)
),
case erlang:element(8, erlang:element(4, S@1)) of
{some, Repeater} ->
repeatedly:set_state(Repeater, erlang:element(4, S@1));
none ->
nil
end,
S@1.
-spec finish(spinner_style()) -> spinner_style().
finish(S) ->
case erlang:element(8, erlang:element(4, S)) of
{some, Repeater} ->
repeatedly_ffi:stop(Repeater);
none ->
nil
end,
gleam@io:println(
<<<<<<(<<"\x{001b}[?25h"/utf8>>)/binary,
(<<"\x{001b}[2K"/utf8>>)/binary>>/binary,
(<<"\r"/utf8>>)/binary>>/binary,
(erlang:element(3, S))/binary>>
),
erlang:setelement(4, S, erlang:setelement(7, erlang:element(4, S), true)).
-spec get_current_frame_string(spinner_style()) -> binary().
get_current_frame_string(S) ->
case glearray:get(
erlang:element(2, erlang:element(2, erlang:element(4, S))),
case erlang:tuple_size(
erlang:element(2, erlang:element(2, erlang:element(4, S)))
) of
0 -> 0;
Gleam@denominator -> erlang:element(6, erlang:element(4, S)) rem Gleam@denominator
end
) of
{ok, F} ->
(erlang:element(3, erlang:element(4, S)))(F);
{error, _} ->
<<""/utf8>>
end.
-spec print_spinner(spinner_style()) -> nil.
print_spinner(S) ->
gleam@io:print(
<<<<<<<<<<(<<"\x{001b}[?25l"/utf8>>)/binary,
(<<"\x{001b}[2K"/utf8>>)/binary>>/binary,
(<<"\r"/utf8>>)/binary>>/binary,
(erlang:element(4, erlang:element(4, S)))/binary>>/binary,
(get_current_frame_string(S))/binary>>/binary,
(erlang:element(5, erlang:element(4, S)))/binary>>
).
-spec spin(spinner_style()) -> spinner_style().
spin(S) ->
Repeater = repeatedly_ffi:call(
erlang:element(2, S),
erlang:element(4, S),
fun(State, _) ->
S@1 = erlang:setelement(4, S, State),
_pipe = tick(S@1),
print_spinner(_pipe),
State
end
),
_pipe@1 = erlang:setelement(
4,
S,
erlang:setelement(8, erlang:element(4, S), {some, Repeater})
),
tick(_pipe@1).