-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).