Packages

A memcached client in pure gleam!

Current section

Files

Jump to
glemcached src glemcached@internal@text.erl
Raw

src/glemcached@internal@text.erl

-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,
<<<<Key@2/binary, " "/utf8>>/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,
<<<<Key@2/binary, " "/utf8>>/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
<<Data:Len@2/bitstring,
"\r\n"/utf8,
Rest@4/bitstring>> ->
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
<<Data:Len@2/bitstring,
"\r\n"/utf8,
Rest@5/bitstring>> ->
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.