Current section

Files

Jump to
glitzer src glitzer@spinner.erl
Raw

src/glitzer@spinner.erl

-module(glitzer@spinner).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/glitzer/spinner.gleam").
-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, get_current_frame_string/1, print_spinner/1, spin/1]).
-export_type([state/0, frames/0, spinner_style/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type state() :: {state,
frames(),
fun((binary()) -> binary()),
binary(),
binary(),
integer(),
boolean(),
gleam@option:option(repeatedly:repeater(state()))}.
-opaque frames() :: {frames, glearray:array(binary())}.
-type spinner_style() :: {spinner_style, integer(), binary(), state()}.
-file("src/glitzer/spinner.gleam", 59).
?DOC(" Convert a given list of `String` to `Frames`.\n").
-spec frames_from_list(list(binary())) -> frames().
frames_from_list(Frames) ->
{frames, erlang:list_to_tuple(Frames)}.
-file("src/glitzer/spinner.gleam", 64).
?DOC(" Create a new spinner from `Frames` with a 100ms tick rate.\n").
-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}}.
-file("src/glitzer/spinner.gleam", 83).
?DOC(" The default spinner.\n").
-spec default_spinner() -> spinner_style().
default_spinner() ->
Frames = [<<"|"/utf8>>, <<"/"/utf8>>, <<"-"/utf8>>, <<"\\"/utf8>>],
new_spinner(frames_from_list(Frames)).
-file("src/glitzer/spinner.gleam", 89).
?DOC(" A spinner with a bar that goes up and down.\n").
-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)).
-file("src/glitzer/spinner.gleam", 99).
?DOC(" A spinner that pulsates.\n").
-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)).
-file("src/glitzer/spinner.gleam", 107).
?DOC(" A spinner that goes from left to right and back.\n").
-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)).
-file("src/glitzer/spinner.gleam", 117).
?DOC(" A spinner that actually spins.\n").
-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)).
-file("src/glitzer/spinner.gleam", 162).
?DOC(" Set the left text of the spinner.\n").
-spec with_left_text(spinner_style(), binary()) -> spinner_style().
with_left_text(S, T) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
T,
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 173).
?DOC(
" Set the frames of the spinner. Useful if you want to update the frames of\n"
" an already running spinner.\n"
).
-spec with_frames(spinner_style(), frames()) -> spinner_style().
with_frames(S, F) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
F,
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 210).
?DOC(
" Set a transformation function that will be applied for each frame. This can\n"
" be every function with the signature `fn(String) -> String`.\n"
"\n"
" <details>\n"
" <summary>Example:</summary>\n"
"\n"
" ```gleam\n"
" import glitzer/spinner\n"
" import gleam_community/ansi\n"
"\n"
" fn example() {\n"
" let s =\n"
" spinner.default_spinner()\n"
" |> spinner.with_frame_transform(ansi.pink) // make all frames pink\n"
" |> spinner.spin\n"
"\n"
" // do some cool stuff\n"
"\n"
" // update the spinner color and the spinner frames\n"
" spinner.with_frame_transform(s, ansi.green)\n"
" |> spinner.with_frames(spinner.frames_from_list([\"a\", \"s\", \"d\", \"f\"]))\n"
"\n"
" // do some other stuff\n"
" \n"
" spinner.finish(s)\n"
" }\n"
" ```\n"
" </details>\n"
).
-spec with_frame_transform(spinner_style(), fun((binary()) -> binary())) -> spinner_style().
with_frame_transform(S, Fun) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
Fun,
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 223).
?DOC(" Set the right text of the spinner.\n").
-spec with_right_text(spinner_style(), binary()) -> spinner_style().
with_right_text(S, T) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
T,
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 233).
?DOC(" Set the spinners tick rate in milliseconds.\n").
-spec with_tick_rate(spinner_style(), integer()) -> spinner_style().
with_tick_rate(S, Ms) ->
_record = S,
{spinner_style, Ms, erlang:element(3, _record), erlang:element(4, _record)}.
-file("src/glitzer/spinner.gleam", 128).
?DOC(
" A very colorful spinner with the colors from the progress pride flag :3\n"
" Note that this spinner has a tick rate of 200 instead of 100 to not flash\n"
" to fast.\n"
).
-spec prideful_spinner() -> spinner_style().
prideful_spinner() ->
Black@1 = case gleam_community@colour:from_rgb255(0, 0, 0) of
{ok, Black} -> Black;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 129,
value => _assert_fail,
start => 3434,
'end' => 3484,
pattern_start => 3445,
pattern_end => 3454})
end,
Brown@1 = case gleam_community@colour:from_rgb255(97, 57, 21) of
{ok, Brown} -> Brown;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 130,
value => _assert_fail@1,
start => 3487,
'end' => 3540,
pattern_start => 3498,
pattern_end => 3507})
end,
Blue@1 = case gleam_community@colour:from_rgb255(116, 215, 238) of
{ok, Blue} -> Blue;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 131,
value => _assert_fail@2,
start => 3543,
'end' => 3598,
pattern_start => 3554,
pattern_end => 3562})
end,
Pink@1 = case gleam_community@colour:from_rgb255(255, 175, 200) of
{ok, Pink} -> Pink;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 132,
value => _assert_fail@3,
start => 3601,
'end' => 3656,
pattern_start => 3612,
pattern_end => 3620})
end,
White@1 = case gleam_community@colour:from_rgb255(255, 255, 255) of
{ok, White} -> White;
_assert_fail@4 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 133,
value => _assert_fail@4,
start => 3659,
'end' => 3715,
pattern_start => 3670,
pattern_end => 3679})
end,
Violet@1 = case gleam_community@colour:from_rgb255(115, 41, 130) of
{ok, Violet} -> Violet;
_assert_fail@5 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 134,
value => _assert_fail@5,
start => 3718,
'end' => 3774,
pattern_start => 3729,
pattern_end => 3739})
end,
Indigo@1 = case gleam_community@colour:from_rgb255(36, 64, 142) of
{ok, Indigo} -> Indigo;
_assert_fail@6 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 135,
value => _assert_fail@6,
start => 3777,
'end' => 3832,
pattern_start => 3788,
pattern_end => 3798})
end,
Green@1 = case gleam_community@colour:from_rgb255(0, 128, 38) of
{ok, Green} -> Green;
_assert_fail@7 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 136,
value => _assert_fail@7,
start => 3835,
'end' => 3888,
pattern_start => 3846,
pattern_end => 3855})
end,
Yellow@1 = case gleam_community@colour:from_rgb255(255, 237, 0) of
{ok, Yellow} -> Yellow;
_assert_fail@8 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 137,
value => _assert_fail@8,
start => 3891,
'end' => 3946,
pattern_start => 3902,
pattern_end => 3912})
end,
Orange@1 = case gleam_community@colour:from_rgb255(255, 140, 0) of
{ok, Orange} -> Orange;
_assert_fail@9 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 138,
value => _assert_fail@9,
start => 3949,
'end' => 4004,
pattern_start => 3960,
pattern_end => 3970})
end,
Red@1 = case gleam_community@colour:from_rgb255(228, 3, 3) of
{ok, Red} -> Red;
_assert_fail@10 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glitzer/spinner"/utf8>>,
function => <<"prideful_spinner"/utf8>>,
line => 139,
value => _assert_fail@10,
start => 4007,
'end' => 4057,
pattern_start => 4018,
pattern_end => 4025})
end,
Frames = [gleam_community@ansi:color(<<"\x{2591}"/utf8>>, Black@1),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Brown@1),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Blue@1),
gleam_community@ansi:color(<<"\x{2588}"/utf8>>, Pink@1),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, White@1),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Violet@1),
gleam_community@ansi:color(<<"\x{2591}"/utf8>>, Indigo@1),
gleam_community@ansi:color(<<"\x{2592}"/utf8>>, Green@1),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Yellow@1),
gleam_community@ansi:color(<<"\x{2588}"/utf8>>, Orange@1),
gleam_community@ansi:color(<<"\x{2593}"/utf8>>, Red@1)],
_pipe = new_spinner(frames_from_list(Frames)),
with_tick_rate(_pipe, 200).
-file("src/glitzer/spinner.gleam", 238).
?DOC(" Set the spinners finish text.\n").
-spec with_finish_text(spinner_style(), binary()) -> spinner_style().
with_finish_text(S, T) ->
_record = S,
{spinner_style, erlang:element(2, _record), T, erlang:element(4, _record)}.
-file("src/glitzer/spinner.gleam", 243).
?DOC(" Progress the spinner by one.\n").
-spec tick(spinner_style()) -> spinner_style().
tick(S) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, erlang:element(4, S)) + 1,
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 254).
?DOC(" Progress the spinner by `i`.\n").
-spec tick_by(spinner_style(), integer()) -> spinner_style().
tick_by(S, I) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, erlang:element(4, S)) + I,
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end}
end,
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.
-file("src/glitzer/spinner.gleam", 296).
?DOC(
" Finish a spinner. If it was countinously ticking, the ticking will be\n"
" stopped. The line will be cleared and the finish text will be printed if\n"
" the spinner had some.\n"
).
-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_stdlib:println(
<<<<<<(<<"\x{001b}[?25h"/utf8>>)/binary,
(<<"\x{001b}[2K"/utf8>>)/binary>>/binary,
(<<"\r"/utf8>>)/binary>>/binary,
(erlang:element(3, S))/binary>>
),
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
begin
_record@1 = erlang:element(4, S),
{state,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
true,
erlang:element(8, _record@1)}
end}.
-file("src/glitzer/spinner.gleam", 323).
-spec get_current_frame_string(spinner_style()) -> binary().
get_current_frame_string(S) ->
case glearray_ffi: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.
-file("src/glitzer/spinner.gleam", 312).
?DOC(
" Print the spinner. This is useful if you need/want manual control over your\n"
" spinner ticks and prints.\n"
).
-spec print_spinner(spinner_style()) -> nil.
print_spinner(S) ->
gleam_stdlib: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>>
).
-file("src/glitzer/spinner.gleam", 280).
?DOC(
" Continuously tick and print the spinner. Note that this **does not** update\n"
" the tick value of your spinner reference!\n"
"\n"
" <details>\n"
" <summary>Example:</summary>\n"
"\n"
" ```gleam\n"
" import glitzer/spinner\n"
"\n"
" fn example() {\n"
" spinner.default_spinner()\n"
" |> spinner.spin\n"
" }\n"
" ```\n"
"\n"
" </details>\n"
).
-spec spin(spinner_style()) -> spinner_style().
spin(S) ->
Repeater = repeatedly_ffi:call(
erlang:element(2, S),
erlang:element(4, S),
fun(State, _) ->
S@1 = begin
_record = S,
{spinner_style,
erlang:element(2, _record),
erlang:element(3, _record),
State}
end,
_pipe = tick(S@1),
print_spinner(_pipe),
State
end
),
_pipe@1 = begin
_record@1 = S,
{spinner_style,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
begin
_record@2 = erlang:element(4, S),
{state,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
erlang:element(4, _record@2),
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
{some, Repeater}}
end}
end,
tick(_pipe@1).