-module(glemcached@internal@text). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([run_text_command/3]). -export_type([text_command/0, storage_command/0, text_response/0, value/0, value_cas/0]). -type text_command() :: {storage_command, storage_command(), binary(), integer(), integer(), integer(), bitstring()} | {get, list(binary())} | {gets, list(binary())} | {delete, binary()} | {incr, binary(), integer()} | {decr, binary(), integer()} | {touch, binary(), integer()} | {get_and_touch, integer(), list(binary())} | {get_and_touchs, integer(), list(binary())}. -type storage_command() :: set | add | replace | append | prepend | {cas, integer()}. -type text_response() :: stored | not_stored | exists | {values, list(value())} | {values_cas, list(value_cas())} | deleted | {raw_value, integer()} | touched | not_found | blank. -type value() :: {value, binary(), integer(), bitstring()}. -type value_cas() :: {value_cas, binary(), integer(), bitstring(), integer()}. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 118). -spec storage_cmd_to_string(storage_command()) -> binary(). storage_cmd_to_string(Cmd) -> case Cmd of set -> <<"set"/utf8>>; add -> <<"add"/utf8>>; replace -> <<"replace"/utf8>>; append -> <<"append"/utf8>>; prepend -> <<"prepend"/utf8>>; {cas, _} -> <<"cas"/utf8>> end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 129). -spec add_no_reply_to_sb(gleam@string_builder:string_builder(), boolean()) -> gleam@string_builder:string_builder(). add_no_reply_to_sb(Sb, No_reply) -> case No_reply of true -> gleam@string_builder:append(Sb, <<" noreply"/utf8>>); false -> Sb end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 136). -spec convert_text_command_to_bb(text_command(), boolean()) -> gleam@bytes_builder:bytes_builder(). convert_text_command_to_bb(Cmd, No_reply) -> case Cmd of {storage_command, Cmd@1, Key, Flags, Exptime, Size, Data} -> _pipe = storage_cmd_to_string(Cmd@1), _pipe@1 = gleam@string_builder:from_string(_pipe), _pipe@2 = gleam@string_builder:append( _pipe@1, gleam@string:join( [<<""/utf8>>, Key, gleam@int:to_string(gleam@int:clamp(Flags, 0, 65535)), gleam@int:to_string(Exptime)], <<" "/utf8>> ) ), _pipe@3 = gleam@string_builder:append( _pipe@2, <<" "/utf8, (gleam@int:to_string(Size))/binary>> ), _pipe@4 = gleam@string_builder:append(_pipe@3, case Cmd@1 of {cas, Cas} -> <<" "/utf8, (gleam@int:to_string(Cas))/binary>>; _ -> <<""/utf8>> end), _pipe@5 = add_no_reply_to_sb(_pipe@4, No_reply), _pipe@6 = gleam@string_builder:append(_pipe@5, <<"\r\n"/utf8>>), _pipe@7 = gleam_stdlib:wrap_list(_pipe@6), _pipe@8 = gleam@bytes_builder:append(_pipe@7, Data), gleam@bytes_builder:append(_pipe@8, <<"\r\n"/utf8>>); {get, Keys} -> _pipe@9 = gleam@string_builder:from_string(case Cmd of {get, _} -> <<"get "/utf8>>; {gets, _} -> <<"gets "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 167}) end), _pipe@10 = gleam@string_builder:append( _pipe@9, gleam@string:join(Keys, <<" "/utf8>>) ), _pipe@11 = gleam@string_builder:append(_pipe@10, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@11); {gets, Keys} -> _pipe@9 = gleam@string_builder:from_string(case Cmd of {get, _} -> <<"get "/utf8>>; {gets, _} -> <<"gets "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 167}) end), _pipe@10 = gleam@string_builder:append( _pipe@9, gleam@string:join(Keys, <<" "/utf8>>) ), _pipe@11 = gleam@string_builder:append(_pipe@10, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@11); {delete, Key@1} -> _pipe@12 = gleam@string_builder:from_string( <<"delete "/utf8, Key@1/binary>> ), _pipe@13 = add_no_reply_to_sb(_pipe@12, No_reply), _pipe@14 = gleam@string_builder:append(_pipe@13, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@14); {incr, Key@2, Value} -> _pipe@15 = gleam@string_builder:from_string(case Cmd of {incr, _, _} -> <<"incr "/utf8>>; {decr, _, _} -> <<"decr "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 183}) end), _pipe@16 = gleam@string_builder:append( _pipe@15, <<<>/binary, (gleam@int:to_string(Value))/binary>> ), _pipe@17 = add_no_reply_to_sb(_pipe@16, No_reply), _pipe@18 = gleam@string_builder:append(_pipe@17, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@18); {decr, Key@2, Value} -> _pipe@15 = gleam@string_builder:from_string(case Cmd of {incr, _, _} -> <<"incr "/utf8>>; {decr, _, _} -> <<"decr "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 183}) end), _pipe@16 = gleam@string_builder:append( _pipe@15, <<<>/binary, (gleam@int:to_string(Value))/binary>> ), _pipe@17 = add_no_reply_to_sb(_pipe@16, No_reply), _pipe@18 = gleam@string_builder:append(_pipe@17, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@18); {touch, Key@3, Exptime@1} -> _pipe@19 = gleam@string_builder:from_string( <<<<<<"touch "/utf8, Key@3/binary>>/binary, " "/utf8>>/binary, (gleam@int:to_string(Exptime@1))/binary>> ), _pipe@20 = add_no_reply_to_sb(_pipe@19, No_reply), _pipe@21 = gleam@string_builder:append(_pipe@20, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@21); {get_and_touch, Exptime@2, Keys@1} -> _pipe@22 = gleam@string_builder:from_string(case Cmd of {get_and_touch, _, _} -> <<"gat "/utf8>>; {get_and_touchs, _, _} -> <<"gats "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 200}) end), _pipe@23 = gleam@string_builder:append( _pipe@22, <<(gleam@int:to_string(Exptime@2))/binary, " "/utf8>> ), _pipe@24 = gleam@string_builder:append( _pipe@23, gleam@string:join(Keys@1, <<" "/utf8>>) ), _pipe@25 = gleam@string_builder:append(_pipe@24, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@25); {get_and_touchs, Exptime@2, Keys@1} -> _pipe@22 = gleam@string_builder:from_string(case Cmd of {get_and_touch, _, _} -> <<"gat "/utf8>>; {get_and_touchs, _, _} -> <<"gats "/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => <<"unreachable"/utf8>>, module => <<"glemcached/internal/text"/utf8>>, function => <<"convert_text_command_to_bb"/utf8>>, line => 200}) end), _pipe@23 = gleam@string_builder:append( _pipe@22, <<(gleam@int:to_string(Exptime@2))/binary, " "/utf8>> ), _pipe@24 = gleam@string_builder:append( _pipe@23, gleam@string:join(Keys@1, <<" "/utf8>>) ), _pipe@25 = gleam@string_builder:append(_pipe@24, <<"\r\n"/utf8>>), gleam_stdlib:wrap_list(_pipe@25) end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 210). -spec parse_values(bitstring(), list(value())) -> {ok, list(value())} | {error, glemcached@types:memcached_error()}. parse_values(Ba, Init) -> case Ba of <<"END\r\n"/utf8>> -> {ok, Init}; <<"VALUE "/utf8, Rest/bitstring>> -> gleam@option:unwrap( begin fun gleam@result:'try'/2, gleam@option:then( glemcached@internal@pop_ba:pop_until_space_on_same_line( Rest ), fun(_use0) -> {Key, Rest@1} = _use0, gleam@option:then( glemcached@internal@pop_ba:pop_until_space_on_same_line( Rest@1 ), fun(_use0@1) -> {Flags, Rest@2} = _use0@1, Flags@1 = gleam@int:clamp( gleam@result:unwrap( gleam@int:parse( gleam@result:unwrap( gleam@bit_array:to_string( Flags ), <<"0"/utf8>> ) ), 0 ), 0, 65535 ), gleam@option:then( glemcached@internal@pop_ba:pop_until_rn( Rest@2 ), fun(_use0@2) -> {Len, Rest@3} = _use0@2, gleam@option:map( begin _pipe = gleam@bit_array:to_string( Len ), _pipe@1 = gleam@result:'try'( _pipe, fun gleam@int:parse/1 ), gleam@option:from_result( _pipe@1 ) end, fun(Len@1) -> Len@2 = Len@1 * 8, case Rest@3 of <> -> case gleam@bit_array:to_string( Key ) of {ok, Key@1} -> V = {value, Key@1, Flags@1, Data}, parse_values( Rest@4, [V | Init] ); _ -> {error, {parse_error, value_parse_error}} end; _ -> {error, {parse_error, value_parse_error}} end end ) end ) end ) end ) end, {error, {parse_error, value_parse_error}} ); _ -> {error, {parse_error, invalid_response}} end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 259). -spec parse_values_cas(bitstring(), list(value_cas())) -> {ok, list(value_cas())} | {error, glemcached@types:memcached_error()}. parse_values_cas(Ba, Init) -> case Ba of <<"END\r\n"/utf8>> -> {ok, Init}; <<"VALUE "/utf8, Rest/bitstring>> -> gleam@option:unwrap( begin fun gleam@result:'try'/2, gleam@option:then( glemcached@internal@pop_ba:pop_until_space_on_same_line( Rest ), fun(_use0) -> {Key, Rest@1} = _use0, gleam@option:then( glemcached@internal@pop_ba:pop_until_space_on_same_line( Rest@1 ), fun(_use0@1) -> {Flags, Rest@2} = _use0@1, Flags@1 = gleam@int:clamp( gleam@result:unwrap( gleam@int:parse( gleam@result:unwrap( gleam@bit_array:to_string( Flags ), <<"0"/utf8>> ) ), 0 ), 0, 65535 ), gleam@option:then( glemcached@internal@pop_ba:pop_until_space_on_same_line( Rest@2 ), fun(_use0@2) -> {Len, Rest@3} = _use0@2, gleam@option:then( begin _pipe = gleam@bit_array:to_string( Len ), _pipe@1 = gleam@result:'try'( _pipe, fun gleam@int:parse/1 ), gleam@option:from_result( _pipe@1 ) end, fun(Len@1) -> Len@2 = Len@1 * 8, gleam@option:then( glemcached@internal@pop_ba:pop_until_rn( Rest@3 ), fun(_use0@3) -> {Cas, Rest@4} = _use0@3, gleam@option:map( begin _pipe@2 = gleam@bit_array:to_string( Cas ), _pipe@3 = gleam@result:'try'( _pipe@2, fun gleam@int:parse/1 ), gleam@option:from_result( _pipe@3 ) end, fun(Cas@1) -> case Rest@4 of <> -> case gleam@bit_array:to_string( Key ) of {ok, Key@1} -> V = {value_cas, Key@1, Flags@1, Data, Cas@1}, parse_values_cas( Rest@5, [V | Init] ); _ -> {error, {parse_error, value_parse_error}} end; _ -> {error, {parse_error, value_parse_error}} end end ) end ) end ) end ) end ) end ) end, {error, {parse_error, value_parse_error}} ); _ -> {error, {parse_error, invalid_response}} end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 313). -spec handle_response(glemcached@types:memcached()) -> {ok, text_response()} | {error, glemcached@types:memcached_error()}. handle_response(Mem) -> Res = mug:'receive'(erlang:element(2, Mem), erlang:element(3, Mem)), case Res of {ok, Val} -> case Val of <<"STORED\r\n"/utf8>> -> {ok, stored}; <<"NOT_STORED\r\n"/utf8>> -> {ok, not_stored}; <<"EXISTS\r\n"/utf8>> -> {ok, exists}; <<"VALUE "/utf8, _/bitstring>> -> case parse_values(Val, []) of {ok, V} -> {ok, {values, V}}; {error, _} -> case parse_values_cas(Val, []) of {ok, V@1} -> {ok, {values_cas, V@1}}; {error, E} -> {error, E} end end; <<"END\r\n"/utf8>> -> case parse_values(Val, []) of {ok, V} -> {ok, {values, V}}; {error, _} -> case parse_values_cas(Val, []) of {ok, V@1} -> {ok, {values_cas, V@1}}; {error, E} -> {error, E} end end; <<"DELETED\r\n"/utf8>> -> {ok, deleted}; <<"TOUCHED\r\n"/utf8>> -> {ok, touched}; <<"NOT_FOUND\r\n"/utf8>> -> {ok, not_found}; <<"ERROR"/utf8>> -> {error, {command_error, general_error}}; <<"CLIENT_ERROR "/utf8, Error/bitstring>> -> {error, {command_error, {client_error, gleam@result:unwrap( gleam@bit_array:to_string(Error), <<"Unknown error"/utf8>> )}}}; <<"SERVER_ERROR "/utf8, Error@1/bitstring>> -> {error, {command_error, {server_error, gleam@result:unwrap( gleam@bit_array:to_string(Error@1), <<"Unknown error"/utf8>> )}}}; _ -> case begin _pipe = glemcached@internal@pop_ba:pop_until_rn(Val), _pipe@1 = gleam@option:unwrap(_pipe, {<<>>, <<>>}), _pipe@2 = (fun(X) -> erlang:element(1, X) end)(_pipe@1), _pipe@3 = gleam@bit_array:to_string(_pipe@2), gleam@result:'try'(_pipe@3, fun gleam@int:parse/1) end of {ok, Val@1} -> {ok, {raw_value, Val@1}}; {error, _} -> {error, {parse_error, invalid_response}} end end; {error, E@1} -> {error, {socket_error, E@1}} end. -file("/home/user/Documents/code/learn/gleam/memcached/src/glemcached/internal/text.gleam", 372). -spec run_text_command(glemcached@types:memcached(), text_command(), boolean()) -> {ok, text_response()} | {error, glemcached@types:memcached_error()}. run_text_command(Mem, Cmd, No_reply) -> _assert_subject = begin _pipe = convert_text_command_to_bb(Cmd, No_reply), mug_ffi:send(erlang:element(2, Mem), _pipe) end, {ok, _} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"glemcached/internal/text"/utf8>>, function => <<"run_text_command"/utf8>>, line => 377}) end, case No_reply of false -> handle_response(Mem); true -> {ok, blank} end.