-module(valkyrie). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/valkyrie.gleam"). -export([host/2, port/2, auth/2, ip_version_preference/2, named_connection/1, shutdown/2, do_execute/3, execute_bits/3, custom/3, key_type_to_string/1, keys/3, scan/6, exists/3, get/3, mget/3, append/4, default_set_options/0, set_options_to_modifiers/1, set/5, mset/3, del/3, incr/3, incrby/4, incrbyfloat/4, decr/3, decrby/4, randomkey/2, key_type/3, rename/4, renamenx/4, persist/3, ping/3, expire_condition_to_modifiers/1, expire/5, pexpire/5, expireat/5, expiretime/3, pexpiretime/3, lpush/4, rpush/4, lpushx/4, rpushx/4, llen/3, lrange/5, lpop/4, rpop/4, lindex/4, lrem/5, lset/5, insert_position_to_string/1, linsert/6, sadd/4, scard/3, sismember/4, smembers/3, sscan/6, score_to_string/1, zadd_build_modifiers_and_members/3, zadd/6, zincrby/5, zcard/3, zcount/5, zscore/4, zscan/6, zrem/4, zrandmember/4, zpopmin/4, zpopmax/4, numeric_bound_to_string/2, zrange/6, zrange_byscore/6, lex_bound_to_string/1, zrange_bylex/6, zrank/4, zrank_withscore/4, zrevrank/4, zrevrank_withscore/4, hset/4, hsetnx/5, hlen/3, hkeys/3, hget/4, hgetall/3, hmget/4, hstrlen/4, hvals/3, hdel/4, hexists/4, hincrby/5, hincrbyfloat/5, hscan/6, create_connection/2, start_pool/4, supervised_pool/4, default_config/0, url_config/1]). -export_type([auth/0, connection/0, pool_error/0, error/0, start_error/0, config/0, url_parse_error/0, key_type/0, set_existence_condition/0, set_expiry_option/0, set_options/0, expire_condition/0, expiration/0, insert_position/0, score/0, z_add_condition/0, numeric_bound/1, lex_bound/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 auth() :: no_auth | {password_only, binary()} | {username_and_password, binary(), binary()}. -opaque connection() :: {single, mug:socket()} | {pooled, gleam@erlang@process:subject(bath:msg(mug:socket()))}. -type pool_error() :: {pooled_resource_create_error, binary()} | no_resources_available. -type error() :: not_found | conflict | {resp_error, binary()} | {connect_error, mug:connect_error()} | timeout | {tcp_error, mug:error()} | {server_error, binary()} | {pool_error, pool_error()}. -type start_error() :: {actor_start_error, gleam@otp@actor:start_error()} | {ping_error, error()}. -type config() :: {config, binary(), integer(), auth(), mug:ip_version_preference()}. -type url_parse_error() :: invalid_uri_format | unsupported_scheme | missing_scheme | missing_host. -type key_type() :: set | list | z_set | hash | string | stream. -type set_existence_condition() :: if_not_exists | if_exists. -type set_expiry_option() :: keep_ttl | {expiry_seconds, integer()} | {expiry_milliseconds, integer()} | {expires_at_unix_seconds, integer()} | {expires_at_unix_milliseconds, integer()}. -type set_options() :: {set_options, gleam@option:option(set_existence_condition()), boolean(), gleam@option:option(set_expiry_option())}. -type expire_condition() :: if_no_expiry | if_has_expiry | if_greater_than | if_less_than. -type expiration() :: {expires_after, integer()} | no_expiration. -type insert_position() :: before | 'after'. -type score() :: infinity | {double, float()} | negative_infinity. -type z_add_condition() :: if_not_exists_in_set | if_exists_in_set | if_score_less_than_existing | if_score_greater_than_existing. -type numeric_bound(HRV) :: {numeric_inclusive, HRV} | {numeric_exclusive, HRV}. -type lex_bound() :: {lex_inclusive, binary()} | {lex_exclusive, binary()} | lex_positive_infinity | lex_negative_infinity. -file("src/valkyrie.gleam", 52). -spec error_to_string(error()) -> binary(). error_to_string(Error) -> case Error of not_found -> <<"Not found"/utf8>>; conflict -> <<"Conflict"/utf8>>; {resp_error, Message} -> <<"RESP protocol error: "/utf8, Message/binary>>; {connect_error, Error@1} -> <<"Failed to connect: "/utf8, (case Error@1 of {connect_failed_both, Ipv4, Ipv6} -> <<<<<<"IPv4 failure: "/utf8, (gleam@string:inspect(Ipv4))/binary>>/binary, "; IPv6 failure: "/utf8>>/binary, (gleam@string:inspect(Ipv6))/binary>>; {connect_failed_ipv4, Ipv4@1} -> <<"IPv4 failure: "/utf8, (gleam@string:inspect(Ipv4@1))/binary>>; {connect_failed_ipv6, Ipv6@1} -> <<"IPv6 failure: "/utf8, (gleam@string:inspect(Ipv6@1))/binary>> end)/binary>>; timeout -> <<"Timeout"/utf8>>; {tcp_error, Error@2} -> <<"TCP error: "/utf8, (gleam@string:inspect(Error@2))/binary>>; {server_error, Message@1} -> Message@1; {pool_error, Error@3} -> <<"Pool error: "/utf8, (case Error@3 of no_resources_available -> <<"No resources available"/utf8>>; {pooled_resource_create_error, Message@2} -> <<"Failed to create resource: "/utf8, Message@2/binary>> end)/binary>> end. -file("src/valkyrie.gleam", 86). -spec auth_to_options_list(auth()) -> list(binary()). auth_to_options_list(Auth) -> case Auth of no_auth -> []; {password_only, Password} -> [<<"AUTH"/utf8>>, <<"default"/utf8>>, Password]; {username_and_password, Username, Password@1} -> [<<"AUTH"/utf8>>, Username, Password@1] end. -file("src/valkyrie.gleam", 121). ?DOC(" Update the host in a Redis configuration.\n"). -spec host(config(), binary()) -> config(). host(Config, Host) -> _record = Config, {config, Host, erlang:element(3, _record), erlang:element(4, _record), erlang:element(5, _record)}. -file("src/valkyrie.gleam", 126). ?DOC(" Update the port in a Redis configuration.\n"). -spec port(config(), integer()) -> config(). port(Config, Port) -> _record = Config, {config, erlang:element(2, _record), Port, erlang:element(4, _record), erlang:element(5, _record)}. -file("src/valkyrie.gleam", 131). ?DOC(" Update the authentication settings in a Redis configuration.\n"). -spec auth(config(), auth()) -> config(). auth(Config, Auth) -> _record = Config, {config, erlang:element(2, _record), erlang:element(3, _record), Auth, erlang:element(5, _record)}. -file("src/valkyrie.gleam", 136). ?DOC(" Update the IP version preference in a Redis configuration.\n"). -spec ip_version_preference(config(), mug:ip_version_preference()) -> config(). ip_version_preference(Config, Preference) -> _record = Config, {config, erlang:element(2, _record), erlang:element(3, _record), erlang:element(4, _record), Preference}. -file("src/valkyrie.gleam", 387). ?DOC(" Create a connection from the process name given to the connection pool.\n"). -spec named_connection(gleam@erlang@process:name(bath:msg(mug:socket()))) -> connection(). named_connection(Name) -> {pooled, gleam@erlang@process:named_subject(Name)}. -file("src/valkyrie.gleam", 399). ?DOC( " Shut down a Redis connection or connection pool.\n" "\n" " For single connections, closes the socket immediately.\n" " For pooled connections, gracefully shuts down the pool with the provided timeout.\n" "\n" " You likely only need to use this function when you're using a single connection or\n" " an unsupervised pool. You should let your supervision tree handle the shutdown of\n" " supervised connection pools.\n" ). -spec shutdown(connection(), integer()) -> {ok, nil} | {error, nil}. shutdown(Conn, Timeout) -> case Conn of {single, Socket} -> _pipe = mug_ffi:shutdown(Socket), gleam@result:replace_error(_pipe, nil); {pooled, Pool} -> _pipe@1 = bath:shutdown(Pool, false, Timeout), gleam@result:replace_error(_pipe@1, nil) end. -file("src/valkyrie.gleam", 465). -spec socket_receive(mug:socket(), bitstring(), integer(), integer()) -> {ok, list(valkyrie@resp:value())} | {error, error()}. socket_receive(Socket, Storage, Start_time, Timeout) -> case valkyrie@resp:decode_value(Storage) of {ok, Value} -> {ok, Value}; {error, _} -> case (valkyrie_ffi:monotonic_now() - Start_time) >= (Timeout * 1000000) of true -> {error, timeout}; false -> case mug:'receive'(Socket, Timeout) of {error, Tcp_error} -> {error, {tcp_error, Tcp_error}}; {ok, Packet} -> socket_receive( Socket, gleam@bit_array:append(Storage, Packet), Start_time, Timeout ) end end end. -file("src/valkyrie.gleam", 451). ?DOC(false). -spec do_execute(mug:socket(), bitstring(), integer()) -> {ok, list(valkyrie@resp:value())} | {error, error()}. do_execute(Socket, Command_bits, Timeout) -> gleam@result:'try'( begin _pipe = mug:send(Socket, Command_bits), gleam@result:map_error( _pipe, fun(Field@0) -> {tcp_error, Field@0} end ) end, fun(_) -> gleam@result:'try'( socket_receive( Socket, <<>>, valkyrie_ffi:monotonic_now(), Timeout ), fun(Reply) -> case Reply of [{simple_error, Error}] -> {error, {server_error, Error}}; [{bulk_error, Error}] -> {error, {server_error, Error}}; Value -> {ok, Value} end end ) end ). -file("src/valkyrie.gleam", 416). ?DOC(false). -spec execute_bits(connection(), bitstring(), integer()) -> {ok, list(valkyrie@resp:value())} | {error, error()}. execute_bits(Conn, Command_bits, Timeout) -> case Conn of {single, Socket} -> do_execute(Socket, Command_bits, Timeout); {pooled, Pool} -> _pipe@3 = bath:apply( Pool, Timeout, fun(Socket@1) -> case do_execute(Socket@1, Command_bits, Timeout) of {ok, Value} -> _pipe = bath:keep(), bath:returning(_pipe, {ok, Value}); {error, Error} -> case Error of {connect_error, _} -> _pipe@1 = bath:discard(), bath:returning(_pipe@1, {error, Error}); {resp_error, _} -> _pipe@1 = bath:discard(), bath:returning(_pipe@1, {error, Error}); {tcp_error, _} -> _pipe@1 = bath:discard(), bath:returning(_pipe@1, {error, Error}); not_found -> _pipe@2 = bath:keep(), bath:returning(_pipe@2, {error, Error}); conflict -> _pipe@2 = bath:keep(), bath:returning(_pipe@2, {error, Error}); {server_error, _} -> _pipe@2 = bath:keep(), bath:returning(_pipe@2, {error, Error}); timeout -> _pipe@2 = bath:keep(), bath:returning(_pipe@2, {error, Error}); {pool_error, _} -> erlang:error(#{gleam_error => panic, message => <<"unreachable - no pool here"/utf8>>, file => <>, module => <<"valkyrie"/utf8>>, function => <<"execute_bits"/utf8>>, line => 433}) end end end ), _pipe@5 = gleam@result:map_error( _pipe@3, fun(Bath_error) -> _pipe@4 = case Bath_error of {check_out_resource_create_error, Error@1} -> {pooled_resource_create_error, Error@1}; no_resources_available -> no_resources_available end, {pool_error, _pipe@4} end ), gleam@result:flatten(_pipe@5) end. -file("src/valkyrie.gleam", 411). -spec execute(connection(), list(binary()), integer()) -> {ok, list(valkyrie@resp:value())} | {error, error()}. execute(Conn, Command, Timeout) -> execute_bits(Conn, valkyrie@resp:encode_command(Command), Timeout). -file("src/valkyrie.gleam", 499). -spec expect_cursor(binary()) -> {ok, integer()} | {error, error()}. expect_cursor(Cursor_string) -> case gleam_stdlib:parse_int(Cursor_string) of {ok, Value} -> {ok, Value}; {error, _} -> {error, {resp_error, <<"Expected integer cursor, got "/utf8, Cursor_string/binary>>}} end. -file("src/valkyrie.gleam", 507). -spec expect_cursor_and_array(list(valkyrie@resp:value())) -> {ok, {list(binary()), integer()}} | {error, error()}. expect_cursor_and_array(Values) -> case Values of [{array, [{bulk_string, New_cursor_str}, {array, Keys}]}] -> gleam@result:'try'( expect_cursor(New_cursor_str), fun(New_cursor) -> gleam@result:'try'( gleam@list:try_map(Keys, fun(Item) -> case Item of {bulk_string, Value} -> {ok, Value}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"string"/utf8>>, [Item] )}} end end), fun(Array) -> {ok, {Array, New_cursor}} end ) end ); _ -> {error, {resp_error, valkyrie@resp:error_string( <<"cursor and array"/utf8>>, Values )}} end. -file("src/valkyrie.gleam", 568). -spec expect_cursor_and_hash_field_array(list(valkyrie@resp:value())) -> {ok, {list({binary(), binary()}), integer()}} | {error, error()}. expect_cursor_and_hash_field_array(Values) -> case Values of [{array, [{bulk_string, New_cursor_str}, {array, Members}]}] -> gleam@result:'try'( expect_cursor(New_cursor_str), fun(New_cursor) -> gleam@result:'try'( begin _pipe = Members, _pipe@1 = gleam@list:sized_chunk(_pipe, 2), gleam@list:try_map( _pipe@1, fun(Item) -> case Item of [{bulk_string, Field}, {bulk_string, Value}] -> {ok, {Field, Value}}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"member and score"/utf8>>, Item )}} end end ) end, fun(Array) -> {ok, {Array, New_cursor}} end ) end ); _ -> {error, {resp_error, valkyrie@resp:error_string( <<"cursor and array"/utf8>>, Values )}} end. -file("src/valkyrie.gleam", 600). -spec expect_integer(list(valkyrie@resp:value())) -> {ok, integer()} | {error, error()}. expect_integer(Value) -> case Value of [{integer, N}] -> {ok, N}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"integer"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 607). -spec expect_nullable_integer(list(valkyrie@resp:value())) -> {ok, integer()} | {error, error()}. expect_nullable_integer(Value) -> case Value of [{integer, N}] -> {ok, N}; [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"integer"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 615). -spec expect_integer_boolean(list(valkyrie@resp:value())) -> {ok, boolean()} | {error, error()}. expect_integer_boolean(Value) -> _pipe = expect_integer(Value), gleam@result:map(_pipe, fun(N) -> N =:= 1 end). -file("src/valkyrie.gleam", 620). -spec expect_float(list(valkyrie@resp:value())) -> {ok, float()} | {error, error()}. expect_float(Value) -> case Value of [{bulk_string, New}] -> case gleam_stdlib:parse_float(New) of {ok, F} -> {ok, F}; {error, _} -> case gleam_stdlib:parse_int(New) of {ok, I} -> {ok, erlang:float(I)}; {error, _} -> {error, {resp_error, <<"Invalid float: "/utf8, New/binary>>}} end end; [{double, Value@1}] -> {ok, Value@1}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"bulk string representation of a float, or double"/utf8>>, Value )}} end. -file("src/valkyrie.gleam", 643). -spec expect_nullable_float(list(valkyrie@resp:value())) -> {ok, float()} | {error, error()}. expect_nullable_float(Value) -> case Value of [{bulk_string, New}] -> case gleam_stdlib:parse_float(New) of {ok, F} -> {ok, F}; {error, _} -> case gleam_stdlib:parse_int(New) of {ok, I} -> {ok, erlang:float(I)}; {error, _} -> {error, {resp_error, <<"Invalid float: "/utf8, New/binary>>}} end end; [{double, Double}] -> {ok, Double}; [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"bulk string representation of a float, double, or null"/utf8>>, Value )}} end. -file("src/valkyrie.gleam", 667). -spec expect_any_string(list(valkyrie@resp:value())) -> {ok, binary()} | {error, error()}. expect_any_string(Value) -> case Value of [{simple_string, Str}] -> {ok, Str}; [{bulk_string, Str}] -> {ok, Str}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"string or null"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 677). -spec expect_simple_string(list(valkyrie@resp:value())) -> {ok, binary()} | {error, error()}. expect_simple_string(Value) -> case Value of [{simple_string, Str}] -> {ok, Str}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"simple string"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 685). -spec expect_nullable_bulk_string(list(valkyrie@resp:value())) -> {ok, binary()} | {error, error()}. expect_nullable_bulk_string(Value) -> case Value of [{bulk_string, Str}] -> {ok, Str}; [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"bulk string or null"/utf8>>, Value )}} end. -file("src/valkyrie.gleam", 696). -spec expect_any_nullable_string(list(valkyrie@resp:value())) -> {ok, binary()} | {error, error()}. expect_any_nullable_string(Value) -> case Value of [{simple_string, Str}] -> {ok, Str}; [{bulk_string, Str}] -> {ok, Str}; [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"string or null"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 707). -spec expect_bulk_string_array(list(valkyrie@resp:value())) -> {ok, list(binary())} | {error, error()}. expect_bulk_string_array(Value) -> case Value of [{array, Array}] -> gleam@list:try_map(Array, fun(Item) -> case Item of {bulk_string, Str} -> {ok, Str}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"bulk string"/utf8>>, [Item] )}} end end); [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"array"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 726). -spec expect_nullable_bulk_string_array(list(valkyrie@resp:value())) -> {ok, list({ok, binary()} | {error, error()})} | {error, error()}. expect_nullable_bulk_string_array(Value) -> case Value of [{array, Array}] -> _pipe = gleam@list:map(Array, fun(Item) -> case Item of {bulk_string, Str} -> {ok, Str}; null -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"string or null"/utf8>>, [Item] )}} end end), {ok, _pipe}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"array"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 767). -spec expect_score(valkyrie@resp:value()) -> {ok, score()} | {error, error()}. expect_score(Value) -> case Value of {double, Value@1} -> {ok, {double, Value@1}}; infinity -> {ok, infinity}; negative_infinity -> {ok, negative_infinity}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"score"/utf8>>, [Value])}} end. -file("src/valkyrie.gleam", 776). -spec expect_sorted_set_member_array(list(valkyrie@resp:value())) -> {ok, list({binary(), score()})} | {error, error()}. expect_sorted_set_member_array(Value) -> case Value of [{array, Members}] -> gleam@result:'try'( begin _pipe = Members, gleam@list:try_map(_pipe, fun(Item) -> case Item of {array, [{bulk_string, Member}, Score]} -> _pipe@1 = expect_score(Score), gleam@result:map( _pipe@1, fun(Score@1) -> {Member, Score@1} end ); _ -> {error, {resp_error, valkyrie@resp:error_string( <<"member and score"/utf8>>, [Item] )}} end end) end, fun(Array) -> {ok, Array} end ); _ -> {error, {resp_error, valkyrie@resp:error_string(<<"array"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 803). -spec expect_nullable_rank_and_score(list(valkyrie@resp:value())) -> {ok, {integer(), score()}} | {error, error()}. expect_nullable_rank_and_score(Value) -> case Value of [{array, [{integer, Rank}, Score]}] -> _pipe = Score, _pipe@1 = expect_score(_pipe), gleam@result:map(_pipe@1, fun(Score@1) -> {Rank, Score@1} end); [null] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"array"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 814). -spec expect_key_type(list(valkyrie@resp:value())) -> {ok, key_type()} | {error, error()}. expect_key_type(Value) -> case Value of [{simple_string, Str}] -> case Str of <<"set"/utf8>> -> {ok, set}; <<"list"/utf8>> -> {ok, list}; <<"zset"/utf8>> -> {ok, z_set}; <<"hash"/utf8>> -> {ok, hash}; <<"string"/utf8>> -> {ok, string}; <<"stream"/utf8>> -> {ok, stream}; <<"none"/utf8>> -> {error, not_found}; _ -> {error, {resp_error, <<"Invalid key type: "/utf8, Str/binary>>}} end; _ -> {error, {resp_error, valkyrie@resp:error_string(<<"key type"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 831). -spec expect_map(list(valkyrie@resp:value())) -> {ok, gleam@dict:dict(valkyrie@resp:value(), valkyrie@resp:value())} | {error, error()}. expect_map(Value) -> case Value of [{map, Map}] -> {ok, Map}; [{array, []}] -> {error, not_found}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"map or empty array"/utf8>>, Value )}} end. -file("src/valkyrie.gleam", 858). ?DOC( " Execute a custom Redis command not already covered by `valkyrie`.\n" "\n" " This function allows you to send any Redis command by providing\n" " the command parts as a list of strings. Useful for new Redis commands\n" " or extensions not yet supported by the library.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " // Execute a custom command like \"CONFIG GET maxmemory\"\n" " let assert Ok(result) = custom(conn, [\"CONFIG\", \"GET\", \"maxmemory\"], 5000)\n" " ```\n" ). -spec custom(connection(), list(binary()), integer()) -> {ok, list(valkyrie@resp:value())} | {error, error()}. custom(Conn, Parts, Timeout) -> execute(Conn, Parts, Timeout). -file("src/valkyrie.gleam", 880). ?DOC(false). -spec key_type_to_string(key_type()) -> binary(). key_type_to_string(Key_type) -> case Key_type of set -> <<"set"/utf8>>; z_set -> <<"zset"/utf8>>; list -> <<"list"/utf8>>; hash -> <<"hash"/utf8>>; string -> <<"string"/utf8>>; stream -> <<"stream"/utf8>> end. -file("src/valkyrie.gleam", 897). ?DOC( " Return all keys matching a pattern.\n" "\n" " **Warning:** This command can be slow on large databases. Consider using\n" " `scan()` or `scan_pattern()` for production use.\n" "\n" " See the [Redis KEYS documentation](https://redis.io/commands/keys) for more details.\n" ). -spec keys(connection(), binary(), integer()) -> {ok, list(binary())} | {error, error()}. keys(Conn, Pattern, Timeout) -> gleam@result:'try'( begin _pipe = valkyrie@internal@commands:keys(Pattern), execute(Conn, _pipe, Timeout) end, fun(Value) -> case Value of [{array, Array}] -> gleam@list:try_map(Array, fun(Item) -> case Item of {bulk_string, Value@1} -> {ok, Value@1}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"string"/utf8>>, [Item] )}} end end); _ -> {error, {resp_error, valkyrie@resp:error_string( <<"string array"/utf8>>, Value )}} end end ). -file("src/valkyrie.gleam", 929). ?DOC( " Iterate incrementally over keys in the database.\n" "\n" " Returns a tuple of `#(keys, next_cursor)`. Use the returned cursor\n" " for subsequent calls. A cursor of 0 indicates the end of iteration.\n" "\n" " You can provide optional pattern or key type filters to limit the keys returned.\n" "\n" " See the [Redis SCAN documentation](https://redis.io/commands/scan) for more details.\n" ). -spec scan( connection(), integer(), gleam@option:option(binary()), integer(), gleam@option:option(key_type()), integer() ) -> {ok, {list(binary()), integer()}} | {error, error()}. scan(Conn, Cursor, Pattern_filter, Count, Key_type_filter, Timeout) -> _pipe = valkyrie@internal@commands:scan( Cursor, Pattern_filter, Count, gleam@option:map(Key_type_filter, fun key_type_to_string/1) ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_cursor_and_array/1). -file("src/valkyrie.gleam", 952). ?DOC( " Check if one or more keys exist.\n" "\n" " Returns the number of keys that exist from the given list.\n" "\n" " See the [Redis EXISTS documentation](https://redis.io/commands/exists) for more details.\n" ). -spec exists(connection(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. exists(Conn, Keys, Timeout) -> _pipe = valkyrie@internal@commands:exists(Keys), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 967). ?DOC( " Get the value of a key.\n" "\n" " Returns `Error(NotFound)` if the key doesn't exist.\n" "\n" " See the [Redis GET documentation](https://redis.io/commands/get) for more details.\n" ). -spec get(connection(), binary(), integer()) -> {ok, binary()} | {error, error()}. get(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:get(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_any_nullable_string/1). -file("src/valkyrie.gleam", 979). ?DOC( " Get the values of multiple keys.\n" "\n" " Returns a list of `Result(String, Error)` values. The value will be\n" " `Error(NotFound)` if the key doesn't exist.\n" "\n" " See the [Redis MGET documentation](https://redis.io/commands/mget) for more details.\n" ). -spec mget(connection(), list(binary()), integer()) -> {ok, list({ok, binary()} | {error, error()})} | {error, error()}. mget(Conn, Keys, Timeout) -> _pipe = valkyrie@internal@commands:mget(Keys), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_bulk_string_array/1). -file("src/valkyrie.gleam", 995). ?DOC( " Append a string to the value at the given key.\n" "\n" " If the key doesn't exist, it creates a new key with the given value.\n" " Returns the new length of the string after appending.\n" "\n" " See the [Redis APPEND documentation](https://redis.io/commands/append) for more details.\n" ). -spec append(connection(), binary(), binary(), integer()) -> {ok, integer()} | {error, error()}. append(Conn, Key, Value, Timeout) -> _pipe = valkyrie@internal@commands:append(Key, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1041). ?DOC( " Default set options.\n" "\n" " | Option | Value |\n" " | ------ | ----- |\n" " | `existence_condition` | `None` |\n" " | `return_old` | `False` |\n" " | `expiry_option` | `None` |\n" ). -spec default_set_options() -> set_options(). default_set_options() -> {set_options, none, false, none}. -file("src/valkyrie.gleam", 1081). ?DOC(false). -spec set_options_to_modifiers(gleam@option:option(set_options())) -> list(binary()). set_options_to_modifiers(Options) -> _pipe = Options, _pipe@1 = gleam@option:map( _pipe, fun(Options@1) -> Modifiers = case erlang:element(4, Options@1) of {some, keep_ttl} -> [<<"KEEPTTL"/utf8>>]; {some, {expiry_seconds, Value}} -> [<<"EX"/utf8>>, erlang:integer_to_binary(Value)]; {some, {expiry_milliseconds, Value@1}} -> [<<"PX"/utf8>>, erlang:integer_to_binary(Value@1)]; {some, {expires_at_unix_seconds, Value@2}} -> [<<"EXAT"/utf8>>, erlang:integer_to_binary(Value@2)]; {some, {expires_at_unix_milliseconds, Value@3}} -> [<<"PXAT"/utf8>>, erlang:integer_to_binary(Value@3)]; none -> [] end, Modifiers@1 = case erlang:element(3, Options@1) of true -> [<<"GET"/utf8>> | Modifiers]; false -> Modifiers end, Modifiers@2 = case erlang:element(2, Options@1) of {some, if_not_exists} -> [<<"NX"/utf8>> | Modifiers@1]; {some, if_exists} -> [<<"XX"/utf8>> | Modifiers@1]; none -> Modifiers@1 end, Modifiers@2 end ), gleam@option:unwrap(_pipe@1, []). -file("src/valkyrie.gleam", 1067). ?DOC( " Set the value of a key with optional conditions and expiry.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // Basic set\n" " let assert Ok(_) = valkyrie.set(conn, \"key\", \"value\", option.None, 5000)\n" "\n" " // Set with expiry\n" " let options = SetOptions(..default_set_options(), expiry_option: option.Some(ExpirySeconds(300)))\n" " let assert Ok(_) = valkyrie.set(conn, \"key\", \"value\", option.Some(options), 5000)\n" "\n" " // Set only if key doesn't exist\n" " let options = SetOptions(..default_set_options(), existence_condition: option.Some(IfNotExists))\n" " let assert Ok(_) = valkyrie.set(conn, \"key\", \"value\", option.Some(options), 5000)\n" " ```\n" "\n" " See the [Redis SET documentation](https://redis.io/commands/set) for more details.\n" ). -spec set( connection(), binary(), binary(), gleam@option:option(set_options()), integer() ) -> {ok, binary()} | {error, error()}. set(Conn, Key, Value, Options, Timeout) -> Modifiers = set_options_to_modifiers(Options), _pipe = valkyrie@internal@commands:set(Key, Value, Modifiers), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_any_nullable_string/1). -file("src/valkyrie.gleam", 748). -spec expect_bulk_string_set(list(valkyrie@resp:value())) -> {ok, gleam@set:set(binary())} | {error, error()}. expect_bulk_string_set(Value) -> case Value of [{set, S}] -> gleam@set:fold( S, {ok, gleam@set:new()}, fun(Acc, Item) -> gleam@result:'try'(Acc, fun(Values) -> case Item of {bulk_string, Str} -> {ok, gleam@set:insert(Values, Str)}; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"bulk string"/utf8>>, [Item] )}} end end) end ); _ -> {error, {resp_error, valkyrie@resp:error_string(<<"set"/utf8>>, Value)}} end. -file("src/valkyrie.gleam", 1116). ?DOC( " Set multiple key-value pairs atomically.\n" "\n" " All keys are set in a single atomic operation.\n" "\n" " See the [Redis MSET documentation](https://redis.io/commands/mset) for more details.\n" ). -spec mset(connection(), list({binary(), binary()}), integer()) -> {ok, binary()} | {error, error()}. mset(Conn, Kv_list, Timeout) -> _pipe = valkyrie@internal@commands:mset(Kv_list), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_any_string/1). -file("src/valkyrie.gleam", 1131). ?DOC( " Delete one or more keys.\n" "\n" " Returns the number of keys that were actually deleted.\n" "\n" " See the [Redis DEL documentation](https://redis.io/commands/del) for more details.\n" ). -spec del(connection(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. del(Conn, Keys, Timeout) -> _pipe = valkyrie@internal@commands:del(Keys), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1147). ?DOC( " Increment the integer value of a key by 1.\n" "\n" " If the key doesn't exist, it's set to 0 before incrementing.\n" " Returns the new value after incrementing.\n" "\n" " See the [Redis INCR documentation](https://redis.io/commands/incr) for more details.\n" ). -spec incr(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. incr(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:incr(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1159). ?DOC( " Increment the integer value of a key by the given amount.\n" "\n" " If the key doesn't exist, it's set to 0 before incrementing.\n" " Returns the new value after incrementing.\n" "\n" " See the [Redis INCRBY documentation](https://redis.io/commands/incrby) for more details.\n" ). -spec incrby(connection(), binary(), integer(), integer()) -> {ok, integer()} | {error, error()}. incrby(Conn, Key, Value, Timeout) -> _pipe = valkyrie@internal@commands:incrby(Key, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1176). ?DOC( " Increment the floating point value of a key by the given amount.\n" "\n" " If the key doesn't exist, it's set to 0 before incrementing.\n" " Returns the new value after incrementing.\n" "\n" " See the [Redis INCRBYFLOAT documentation](https://redis.io/commands/incrbyfloat) for more details.\n" ). -spec incrbyfloat(connection(), binary(), float(), integer()) -> {ok, float()} | {error, error()}. incrbyfloat(Conn, Key, Value, Timeout) -> _pipe = valkyrie@internal@commands:incrbyfloat(Key, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_float/1). -file("src/valkyrie.gleam", 1193). ?DOC( " Decrement the integer value of a key by 1.\n" "\n" " If the key doesn't exist, it's set to 0 before decrementing.\n" " Returns the new value after decrementing.\n" "\n" " See the [Redis DECR documentation](https://redis.io/commands/decr) for more details.\n" ). -spec decr(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. decr(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:decr(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1205). ?DOC( " Decrement the integer value of a key by the given amount.\n" "\n" " If the key doesn't exist, it's set to 0 before decrementing.\n" " Returns the new value after decrementing.\n" "\n" " See the [Redis DECRBY documentation](https://redis.io/commands/decrby) for more details.\n" ). -spec decrby(connection(), binary(), integer(), integer()) -> {ok, integer()} | {error, error()}. decrby(Conn, Key, Value, Timeout) -> _pipe = valkyrie@internal@commands:decrby(Key, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1221). ?DOC( " Return a random key from the database.\n" "\n" " Returns `Error(NotFound)` if the database is empty.\n" "\n" " See the [Redis RANDOMKEY documentation](https://redis.io/commands/randomkey) for more details.\n" ). -spec randomkey(connection(), integer()) -> {ok, binary()} | {error, error()}. randomkey(Conn, Timeout) -> _pipe = valkyrie@internal@commands:randomkey(), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_bulk_string/1). -file("src/valkyrie.gleam", 1232). ?DOC( " Get the type of a key.\n" "\n" " Returns the data type stored at the key.\n" "\n" " See the [Redis TYPE documentation](https://redis.io/commands/type) for more details.\n" ). -spec key_type(connection(), binary(), integer()) -> {ok, key_type()} | {error, error()}. key_type(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:key_type(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_key_type/1). -file("src/valkyrie.gleam", 1248). ?DOC( " Rename a key.\n" "\n" " If the new key already exists, it will be overwritten.\n" " Returns an error if the source key doesn't exist.\n" "\n" " See the [Redis RENAME documentation](https://redis.io/commands/rename) for more details.\n" ). -spec rename(connection(), binary(), binary(), integer()) -> {ok, binary()} | {error, error()}. rename(Conn, Key, New_key, Timeout) -> _pipe = valkyrie@internal@commands:rename(Key, New_key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_simple_string/1). -file("src/valkyrie.gleam", 1264). ?DOC( " Rename a key only if the new key doesn't exist.\n" "\n" " Returns 1 if the key was renamed, 0 if the new key already exists.\n" "\n" " See the [Redis RENAMENX documentation](https://redis.io/commands/renamenx) for more details.\n" ). -spec renamenx(connection(), binary(), binary(), integer()) -> {ok, integer()} | {error, error()}. renamenx(Conn, Key, New_key, Timeout) -> _pipe = valkyrie@internal@commands:renamenx(Key, New_key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1280). ?DOC( " Remove the expiration from a key.\n" "\n" " Returns 1 if the timeout was removed, 0 if the key doesn't exist or has no timeout.\n" "\n" " See the [Redis PERSIST documentation](https://redis.io/commands/persist) for more details.\n" ). -spec persist(connection(), binary(), integer()) -> {ok, boolean()} | {error, error()}. persist(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:persist(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 1296). ?DOC( " Ping the Redis server.\n" "\n" " If no message is provided, returns \"PONG\" if the server is responding.\n" " Otherwise, returns the provided message if the server is responding.\n" "\n" " See the [Redis PING documentation](https://redis.io/commands/ping) for more details.\n" ). -spec ping(connection(), gleam@option:option(binary()), integer()) -> {ok, binary()} | {error, error()}. ping(Conn, Message, Timeout) -> Expected = case Message of none -> <<"PONG"/utf8>>; {some, Msg} -> Msg end, _pipe = valkyrie@internal@commands:ping(Message), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun(Value) -> case Value of [{simple_string, Got}] when Got =:= Expected -> {ok, Got}; [{bulk_string, Got}] when Got =:= Expected -> {ok, Got}; _ -> {error, {resp_error, valkyrie@resp:error_string(Expected, Value)}} end end). -file("src/valkyrie.gleam", 1352). ?DOC(false). -spec expire_condition_to_modifiers(gleam@option:option(expire_condition())) -> list(binary()). expire_condition_to_modifiers(Condition) -> case Condition of {some, if_no_expiry} -> [<<"NX"/utf8>>]; {some, if_has_expiry} -> [<<"XX"/utf8>>]; {some, if_greater_than} -> [<<"GT"/utf8>>]; {some, if_less_than} -> [<<"LT"/utf8>>]; none -> [] end. -file("src/valkyrie.gleam", 1338). ?DOC( " Set a TTL in seconds on a key, relative to the current time.\n" "\n" " Returns `True` if the timeout was set, `False` if the key doesn't exist or the\n" " condition wasn't met.\n" "\n" " **Note:** KeyDB does not support the `EXPIRE` command's conditional behaviour.\n" " Make sure to pass `option.None` if to the `condition` argument if you're using\n" " KeyDB.\n" "\n" " See the [Redis EXPIRE documentation](https://redis.io/commands/expire) for more details.\n" ). -spec expire( connection(), binary(), integer(), gleam@option:option(expire_condition()), integer() ) -> {ok, boolean()} | {error, error()}. expire(Conn, Key, Ttl, Condition, Timeout) -> Expiry_condition = expire_condition_to_modifiers(Condition), _pipe = valkyrie@internal@commands:expire(Key, Ttl, Expiry_condition), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 1374). ?DOC( " Set a TTL in milliseconds on a key, relative to the current time.\n" "\n" " Returns `True` if the timeout was set, `False` if the key doesn't exist or the\n" " condition wasn't met.\n" "\n" " **Note:** KeyDB does not support the `PEXPIRE` command's conditional behaviour.\n" " Make sure to pass `option.None` if to the `condition` argument if you're using\n" " KeyDB.\n" "\n" " See the [Redis PEXPIRE documentation](https://redis.io/commands/pexpire) for more details.\n" ). -spec pexpire( connection(), binary(), integer(), gleam@option:option(expire_condition()), integer() ) -> {ok, boolean()} | {error, error()}. pexpire(Conn, Key, Ttl, Condition, Timeout) -> Expiry_condition = expire_condition_to_modifiers(Condition), _pipe = valkyrie@internal@commands:pexpire(Key, Ttl, Expiry_condition), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 1398). ?DOC( " Set an absolute expiry on a key.\n" "\n" " The expiry is specified as a Unix timestamp. If the timeout is in the past, the\n" " key will be deleted immediately. Returns `True` if the timeout was set, `False` if\n" " the key doesn't exist or the condition wasn't met.\n" "\n" " **Note:** KeyDB does not support the `EXPIREAT` command's conditional behaviour.\n" " Make sure to pass `option.None` if to the `condition` argument if you're using\n" " KeyDB.\n" "\n" " See the [Redis EXPIREAT documentation](https://redis.io/commands/expireat) for more details.\n" ). -spec expireat( connection(), binary(), gleam@time@timestamp:timestamp(), gleam@option:option(expire_condition()), integer() ) -> {ok, boolean()} | {error, error()}. expireat(Conn, Key, Ts, Condition, Timeout) -> Expiry_condition = expire_condition_to_modifiers(Condition), Unix_seconds = begin _pipe = Ts, _pipe@1 = gleam@time@timestamp:to_unix_seconds(_pipe), erlang:round(_pipe@1) end, _pipe@2 = valkyrie@internal@commands:expireat( Key, Unix_seconds, Expiry_condition ), _pipe@3 = execute(Conn, _pipe@2, Timeout), gleam@result:'try'(_pipe@3, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 1429). ?DOC( " Returns the absolute Unix timestamp (since January 1, 1970) in seconds at which the\n" " given key will expire.\n" "\n" " Will return `Ok(NoExpiration)` if the key has no associated expiration, or\n" " `Error(NotFound)` if the key does not exist.\n" "\n" " **Note:** KeyDB does not support the `EXPIRETIME` command.\n" "\n" " See the [Redis EXPIRETIME documentation](https://redis.io/commands/expiretime) for more details.\n" ). -spec expiretime(connection(), binary(), integer()) -> {ok, expiration()} | {error, error()}. expiretime(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:expiretime(Key), _pipe@1 = execute(Conn, _pipe, Timeout), _pipe@2 = gleam@result:'try'(_pipe@1, fun expect_integer/1), gleam@result:'try'(_pipe@2, fun(Value) -> case Value of -2 -> {error, not_found}; -1 -> {ok, no_expiration}; _ -> {ok, {expires_after, Value}} end end). -file("src/valkyrie.gleam", 1455). ?DOC( " Returns the absolute Unix timestamp (since January 1, 1970) in milliseconds at\n" " which the given key will expire.\n" "\n" " Will return `Ok(NoExpiration)` if the key has no associated expiration, or\n" " `Error(NotFound)` if the key does not exist.\n" "\n" " **Note:** KeyDB does not support the `PEXPIRETIME` command.\n" "\n" " See the [Redis PEXPIRETIME documentation](https://redis.io/commands/pexpiretime) for more details.\n" ). -spec pexpiretime(connection(), binary(), integer()) -> {ok, expiration()} | {error, error()}. pexpiretime(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:pexpiretime(Key), _pipe@1 = execute(Conn, _pipe, Timeout), _pipe@2 = gleam@result:'try'(_pipe@1, fun expect_integer/1), gleam@result:'try'(_pipe@2, fun(Value) -> case Value of -2 -> {error, not_found}; -1 -> {ok, no_expiration}; _ -> {ok, {expires_after, Value}} end end). -file("src/valkyrie.gleam", 1481). ?DOC( " Push one or more values to the left (head) of a list.\n" "\n" " Creates the list if it doesn't exist. Returns the new length of the list.\n" "\n" " See the [Redis LPUSH documentation](https://redis.io/commands/lpush) for more details.\n" ). -spec lpush(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. lpush(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:lpush(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1497). ?DOC( " Push one or more values to the right (tail) of a list.\n" "\n" " Creates the list if it doesn't exist. Returns the new length of the list.\n" "\n" " See the [Redis RPUSH documentation](https://redis.io/commands/rpush) for more details.\n" ). -spec rpush(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. rpush(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:rpush(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1513). ?DOC( " Push values to the left (head) of a list, only if the list already exists.\n" "\n" " Returns 0 if the key doesn't exist, otherwise returns the new length of the list.\n" "\n" " See the [Redis LPUSHX documentation](https://redis.io/commands/lpushx) for more details.\n" ). -spec lpushx(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. lpushx(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:lpushx(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1529). ?DOC( " Push values to the right (tail) of a list, only if the list already exists.\n" "\n" " Returns 0 if the key doesn't exist, otherwise returns the new length of the list.\n" "\n" " See the [Redis RPUSHX documentation](https://redis.io/commands/rpushx) for more details.\n" ). -spec rpushx(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. rpushx(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:rpushx(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1545). ?DOC( " Get the length of a list.\n" "\n" " Returns 0 if the key doesn't exist or is not a list.\n" "\n" " See the [Redis LLEN documentation](https://redis.io/commands/llen) for more details.\n" ). -spec llen(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. llen(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:llen(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1557). ?DOC( " Get a range of elements from a list.\n" "\n" " Both start and end are zero-based indexes. Negative numbers can be used\n" " to designate elements starting from the tail of the list.\n" "\n" " See the [Redis LRANGE documentation](https://redis.io/commands/lrange) for more details.\n" ). -spec lrange(connection(), binary(), integer(), integer(), integer()) -> {ok, list(binary())} | {error, error()}. lrange(Conn, Key, Start, End, Timeout) -> _pipe = valkyrie@internal@commands:lrange(Key, Start, End), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 1574). ?DOC( " Remove and return elements from the left (head) of a list.\n" "\n" " Returns `Error(NotFound)` if the key doesn't exist or the list is empty.\n" "\n" " See the [Redis LPOP documentation](https://redis.io/commands/lpop) for more details.\n" ). -spec lpop(connection(), binary(), integer(), integer()) -> {ok, list(binary())} | {error, error()}. lpop(Conn, Key, Count, Timeout) -> _pipe = valkyrie@internal@commands:lpop(Key, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 1590). ?DOC( " Remove and return elements from the right (tail) of a list.\n" "\n" " Returns `Error(NotFound)` if the key doesn't exist or the list is empty.\n" "\n" " See the [Redis RPOP documentation](https://redis.io/commands/rpop) for more details.\n" ). -spec rpop(connection(), binary(), integer(), integer()) -> {ok, list(binary())} | {error, error()}. rpop(Conn, Key, Count, Timeout) -> _pipe = valkyrie@internal@commands:rpop(Key, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 1607). ?DOC( " Get an element from a list by its index.\n" "\n" " Index is zero-based. Negative indices count from the end (-1 is the last element).\n" " Returns `Error(NotFound)` if the index is out of range.\n" "\n" " See the [Redis LINDEX documentation](https://redis.io/commands/lindex) for more details.\n" ). -spec lindex(connection(), binary(), integer(), integer()) -> {ok, binary()} | {error, error()}. lindex(Conn, Key, Index, Timeout) -> _pipe = valkyrie@internal@commands:lindex(Key, Index), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_bulk_string/1). -file("src/valkyrie.gleam", 1627). ?DOC( " Remove elements equal to value from a list.\n" "\n" " - count > 0: Remove elements equal to value moving from head to tail\n" " - count < 0: Remove elements equal to value moving from tail to head\n" " - count = 0: Remove all elements equal to value\n" "\n" " Returns the number of removed elements.\n" "\n" " See the [Redis LREM documentation](https://redis.io/commands/lrem) for more details.\n" ). -spec lrem(connection(), binary(), integer(), binary(), integer()) -> {ok, integer()} | {error, error()}. lrem(Conn, Key, Count, Value, Timeout) -> _pipe = valkyrie@internal@commands:lrem(Key, Count, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1644). ?DOC( " Set the value of an element in a list by its index.\n" "\n" " Index is zero-based. Returns an error if the index is out of range.\n" "\n" " See the [Redis LSET documentation](https://redis.io/commands/lset) for more details.\n" ). -spec lset(connection(), binary(), integer(), binary(), integer()) -> {ok, binary()} | {error, error()}. lset(Conn, Key, Index, Value, Timeout) -> _pipe = valkyrie@internal@commands:lset(Key, Index, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_simple_string/1). -file("src/valkyrie.gleam", 1682). ?DOC(false). -spec insert_position_to_string(insert_position()) -> binary(). insert_position_to_string(Position) -> case Position of before -> <<"BEFORE"/utf8>>; 'after' -> <<"AFTER"/utf8>> end. -file("src/valkyrie.gleam", 1667). ?DOC( " Insert an element before or after another element in a list.\n" "\n" " Returns the new length of the list, or -1 if the pivot element wasn't found.\n" " Returns 0 if the key doesn't exist.\n" "\n" " See the [Redis LINSERT documentation](https://redis.io/commands/linsert) for more details.\n" ). -spec linsert( connection(), binary(), insert_position(), binary(), binary(), integer() ) -> {ok, integer()} | {error, error()}. linsert(Conn, Key, Position, Pivot, Value, Timeout) -> Position_str = insert_position_to_string(Position), _pipe = valkyrie@internal@commands:linsert(Key, Position_str, Pivot, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1699). ?DOC( " Add one or more members to a set.\n" "\n" " Creates the set if it doesn't exist. Returns the number of members that were\n" " actually added to the set (not including members that were already present).\n" "\n" " See the [Redis SADD documentation](https://redis.io/commands/sadd) for more details.\n" ). -spec sadd(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. sadd(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:sadd(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1715). ?DOC( " Get the number of members in a set.\n" "\n" " Returns 0 if the key doesn't exist.\n" "\n" " See the [Redis SCARD documentation](https://redis.io/commands/scard) for more details.\n" ). -spec scard(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. scard(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:scard(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1727). ?DOC( " Check if a value is a member of a set.\n" "\n" " Returns `True` if the value is a member of the set, `False` otherwise.\n" " Returns `False` if the key doesn't exist.\n" "\n" " See the [Redis SISMEMBER documentation](https://redis.io/commands/sismember) for more details.\n" ). -spec sismember(connection(), binary(), binary(), integer()) -> {ok, boolean()} | {error, error()}. sismember(Conn, Key, Value, Timeout) -> _pipe = valkyrie@internal@commands:sismember(Key, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 1746). ?DOC( " Get all members of a set.\n" "\n" " Returns an empty set if the key doesn't exist.\n" "\n" " **Warning:** This command can be slow on large sets. Consider using\n" " `sscan()` for production use with large sets.\n" "\n" " See the [Redis SMEMBERS documentation](https://redis.io/commands/smembers) for more details.\n" ). -spec smembers(connection(), binary(), integer()) -> {ok, gleam@set:set(binary())} | {error, error()}. smembers(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:smembers(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_set/1). -file("src/valkyrie.gleam", 1765). ?DOC( " Iterate incrementally over members of a set.\n" "\n" " Returns a tuple of `#(members, next_cursor)`. Use the returned cursor\n" " for subsequent calls. A cursor of 0 indicates the end of iteration.\n" "\n" " This is the recommended way to iterate over large sets in production\n" " environments as it doesn't block the server like `smembers()`.\n" "\n" " See the [Redis SSCAN documentation](https://redis.io/commands/sscan) for more details.\n" ). -spec sscan( connection(), binary(), integer(), gleam@option:option(binary()), integer(), integer() ) -> {ok, {list(binary()), integer()}} | {error, error()}. sscan(Conn, Key, Cursor, Pattern_filter, Count, Timeout) -> _pipe = valkyrie@internal@commands:sscan(Key, Cursor, Pattern_filter, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_cursor_and_array/1). -file("src/valkyrie.gleam", 1789). ?DOC(false). -spec score_to_string(score()) -> binary(). score_to_string(Score) -> case Score of infinity -> <<"+inf"/utf8>>; negative_infinity -> <<"-inf"/utf8>>; {double, Value} -> gleam_stdlib:float_to_string(Value) end. -file("src/valkyrie.gleam", 1797). -spec score_from_string(binary()) -> {ok, score()} | {error, nil}. score_from_string(Score) -> case Score of <<"+inf"/utf8>> -> {ok, infinity}; <<"inf"/utf8>> -> {ok, infinity}; <<"-inf"/utf8>> -> {ok, negative_infinity}; _ -> case gleam_stdlib:parse_int(Score) of {ok, Score@1} -> _pipe = Score@1, _pipe@1 = erlang:float(_pipe), _pipe@2 = {double, _pipe@1}, {ok, _pipe@2}; {error, nil} -> _pipe@3 = Score, _pipe@4 = gleam_stdlib:parse_float(_pipe@3), gleam@result:map( _pipe@4, fun(Field@0) -> {double, Field@0} end ) end end. -file("src/valkyrie.gleam", 533). -spec expect_cursor_and_sorted_set_member_array(list(valkyrie@resp:value())) -> {ok, {list({binary(), score()}), integer()}} | {error, error()}. expect_cursor_and_sorted_set_member_array(Values) -> case Values of [{array, [{bulk_string, New_cursor_str}, {array, Members}]}] -> gleam@result:'try'( expect_cursor(New_cursor_str), fun(New_cursor) -> gleam@result:'try'( begin _pipe = Members, _pipe@1 = gleam@list:sized_chunk(_pipe, 2), gleam@list:try_map( _pipe@1, fun(Item) -> case Item of [{bulk_string, Member}, {bulk_string, Score}] -> case score_from_string(Score) of {ok, Score@1} -> {ok, {Member, Score@1}}; _ -> {error, {resp_error, <<"Invalid score: "/utf8, Score/binary>>}} end; _ -> {error, {resp_error, valkyrie@resp:error_string( <<"member and score"/utf8>>, Item )}} end end ) end, fun(Array) -> {ok, {Array, New_cursor}} end ) end ); _ -> {error, {resp_error, valkyrie@resp:error_string( <<"cursor and array"/utf8>>, Values )}} end. -file("src/valkyrie.gleam", 1869). ?DOC(false). -spec zadd_build_modifiers_and_members( list({binary(), score()}), z_add_condition(), boolean() ) -> list(binary()). zadd_build_modifiers_and_members(Members, Condition, Return_changed) -> Changed_modifier = case Return_changed of true -> [<<"CH"/utf8>>]; false -> [] end, Modifiers = case Condition of if_not_exists_in_set -> [<<"NX"/utf8>> | Changed_modifier]; if_exists_in_set -> [<<"XX"/utf8>> | Changed_modifier]; if_score_less_than_existing -> [<<"XX"/utf8>>, <<"LT"/utf8>> | Changed_modifier]; if_score_greater_than_existing -> [<<"XX"/utf8>>, <<"GT"/utf8>> | Changed_modifier] end, lists:append( Modifiers, gleam@list:flat_map( Members, fun(Member) -> [score_to_string(erlang:element(2, Member)), erlang:element(1, Member)] end ) ). -file("src/valkyrie.gleam", 1845). ?DOC( " Add one or more members with scores to a sorted set.\n" "\n" " Creates the sorted set if it doesn't exist. The return value depends on the\n" " `return_changed` parameter:\n" " - If `False`: returns the number of new members added\n" " - If `True`: returns the number of members added or updated\n" "\n" " The `condition` parameter controls when the operation should proceed:\n" " - `IfNotExistsInSet`: Only add new members (like NX option)\n" " - `IfExistsInSet`: Only update existing members (like XX option)\n" " - `IfScoreLessThanExisting`: Only update if new score is less than existing\n" " - `IfScoreGreaterThanExisting`: Only update if new score is greater than existing\n" "\n" " Returns `Error(Conflict)` if the operation was aborted due to a conflict with one\n" " of the options.\n" "\n" " See the [Redis ZADD documentation](https://redis.io/commands/zadd) for more details.\n" ). -spec zadd( connection(), binary(), list({binary(), score()}), z_add_condition(), boolean(), integer() ) -> {ok, integer()} | {error, error()}. zadd(Conn, Key, Members, Condition, Return_changed, Timeout) -> Modifiers_and_members = zadd_build_modifiers_and_members( Members, Condition, Return_changed ), _pipe = valkyrie@internal@commands:zadd(Key, Modifiers_and_members), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'( _pipe@1, fun(Value) -> case expect_nullable_integer(Value) of {ok, Integer} -> {ok, Integer}; {error, not_found} -> {error, conflict}; {error, Error} -> {error, Error} end end ). -file("src/valkyrie.gleam", 1896). ?DOC( " Increment the score of a member in a sorted set.\n" "\n" " If the member doesn't exist, it's added with the given score as its initial value.\n" " Returns the new score of the member after incrementing.\n" "\n" " See the [Redis ZINCRBY documentation](https://redis.io/commands/zincrby) for more details.\n" ). -spec zincrby(connection(), binary(), binary(), score(), integer()) -> {ok, float()} | {error, error()}. zincrby(Conn, Key, Member, Delta, Timeout) -> _pipe = valkyrie@internal@commands:zincrby( Key, score_to_string(Delta), Member ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_float/1). -file("src/valkyrie.gleam", 1913). ?DOC( " Get the number of members in a sorted set.\n" "\n" " Returns 0 if the key doesn't exist.\n" "\n" " See the [Redis ZCARD documentation](https://redis.io/commands/zcard) for more details.\n" ). -spec zcard(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. zcard(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:zcard(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1925). ?DOC( " Count the members in a sorted set within a score range.\n" "\n" " Both `min` and `max` scores are inclusive by default. Use `Score` variants\n" " to specify infinity bounds for open-ended ranges.\n" "\n" " See the [Redis ZCOUNT documentation](https://redis.io/commands/zcount) for more details.\n" ). -spec zcount(connection(), binary(), score(), score(), integer()) -> {ok, integer()} | {error, error()}. zcount(Conn, Key, Min, Max, Timeout) -> _pipe = valkyrie@internal@commands:zcount( Key, score_to_string(Min), score_to_string(Max) ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1942). ?DOC( " Get the score of a member in a sorted set.\n" "\n" " Returns `Error(NotFound)` if the key doesn't exist or the member is not in the set.\n" "\n" " See the [Redis ZSCORE documentation](https://redis.io/commands/zscore) for more details.\n" ). -spec zscore(connection(), binary(), binary(), integer()) -> {ok, float()} | {error, error()}. zscore(Conn, Key, Member, Timeout) -> _pipe = valkyrie@internal@commands:zscore(Key, Member), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_float/1). -file("src/valkyrie.gleam", 1962). ?DOC( " Iterate incrementally over members and scores of a sorted set.\n" "\n" " Returns a tuple of `#(members_with_scores, next_cursor)`. Use the returned cursor\n" " for subsequent calls. A cursor of 0 indicates the end of iteration.\n" "\n" " This is the recommended way to iterate over large sorted sets in production\n" " environments.\n" "\n" " See the [Redis ZSCAN documentation](https://redis.io/commands/zscan) for more details.\n" ). -spec zscan( connection(), binary(), integer(), gleam@option:option(binary()), integer(), integer() ) -> {ok, {list({binary(), score()}), integer()}} | {error, error()}. zscan(Conn, Key, Cursor, Pattern_filter, Count, Timeout) -> _pipe = valkyrie@internal@commands:zscan(Key, Cursor, Pattern_filter, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_cursor_and_sorted_set_member_array/1). -file("src/valkyrie.gleam", 1981). ?DOC( " Remove one or more members from a sorted set.\n" "\n" " Returns the number of members that were actually removed from the set\n" " (not including members that were not present).\n" "\n" " See the [Redis ZREM documentation](https://redis.io/commands/zrem) for more details.\n" ). -spec zrem(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. zrem(Conn, Key, Members, Timeout) -> _pipe = valkyrie@internal@commands:zrem(Key, Members), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 1998). ?DOC( " Return random members from a sorted set with their scores.\n" "\n" " Returns up to `count` random members. The members are returned with their scores.\n" " If the sorted set is smaller than `count`, all members are returned.\n" "\n" " See the [Redis ZRANDMEMBER documentation](https://redis.io/commands/zrandmember) for more details.\n" ). -spec zrandmember(connection(), binary(), integer(), integer()) -> {ok, list({binary(), score()})} | {error, error()}. zrandmember(Conn, Key, Count, Timeout) -> _pipe = valkyrie@internal@commands:zrandmember(Key, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_sorted_set_member_array/1). -file("src/valkyrie.gleam", 2015). ?DOC( " Remove and return members with the lowest scores from a sorted set.\n" "\n" " Returns up to `count` members with the lowest scores. The members are removed\n" " from the sorted set and returned with their scores.\n" "\n" " See the [Redis ZPOPMIN documentation](https://redis.io/commands/zpopmin) for more details.\n" ). -spec zpopmin(connection(), binary(), integer(), integer()) -> {ok, list({binary(), score()})} | {error, error()}. zpopmin(Conn, Key, Count, Timeout) -> _pipe = valkyrie@internal@commands:zpopmin(Key, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_sorted_set_member_array/1). -file("src/valkyrie.gleam", 2032). ?DOC( " Remove and return members with the highest scores from a sorted set.\n" "\n" " Returns up to `count` members with the highest scores. The members are removed\n" " from the sorted set and returned with their scores.\n" "\n" " See the [Redis ZPOPMAX documentation](https://redis.io/commands/zpopmax) for more details.\n" ). -spec zpopmax(connection(), binary(), integer(), integer()) -> {ok, list({binary(), score()})} | {error, error()}. zpopmax(Conn, Key, Count, Timeout) -> _pipe = valkyrie@internal@commands:zpopmax(Key, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_sorted_set_member_array/1). -file("src/valkyrie.gleam", 2049). ?DOC(false). -spec numeric_bound_to_string(numeric_bound(IBM), fun((IBM) -> binary())) -> binary(). numeric_bound_to_string(Bound, To_string_func) -> case Bound of {numeric_inclusive, Value} -> To_string_func(Value); {numeric_exclusive, Value@1} -> <<"("/utf8, (To_string_func(Value@1))/binary>> end. -file("src/valkyrie.gleam", 2068). ?DOC( " Get a range of members from a sorted set by rank (index).\n" "\n" " Returns members with their scores in the specified rank range.\n" " Ranks are 0-based, with 0 being the member with the lowest score.\n" " Use `NumericBound` to specify inclusive or exclusive bounds.\n" "\n" " If `reverse` is `True`, returns members in descending score order.\n" "\n" " See the [Redis ZRANGE documentation](https://redis.io/commands/zrange) for more details.\n" ). -spec zrange( connection(), binary(), numeric_bound(integer()), numeric_bound(integer()), boolean(), integer() ) -> {ok, list({binary(), score()})} | {error, error()}. zrange(Conn, Key, Start, Stop, Reverse, Timeout) -> Modifiers = case Reverse of true -> [<<"REV"/utf8>>, <<"WITHSCORES"/utf8>>]; false -> [<<"WITHSCORES"/utf8>>] end, _pipe = valkyrie@internal@commands:zrange( Key, numeric_bound_to_string(Start, fun erlang:integer_to_binary/1), numeric_bound_to_string(Stop, fun erlang:integer_to_binary/1), Modifiers ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_sorted_set_member_array/1). -file("src/valkyrie.gleam", 2099). ?DOC( " Get a range of members from a sorted set by score.\n" "\n" " Returns all members with scores within the specified score range.\n" " Use `NumericBound` with `Score` values to specify inclusive or exclusive bounds,\n" " including infinity bounds for open-ended ranges.\n" "\n" " If `reverse` is `True`, returns members in descending score order.\n" "\n" " See the [Redis ZRANGE documentation](https://redis.io/commands/zrange) for more details.\n" ). -spec zrange_byscore( connection(), binary(), numeric_bound(score()), numeric_bound(score()), boolean(), integer() ) -> {ok, list({binary(), score()})} | {error, error()}. zrange_byscore(Conn, Key, Start, Stop, Reverse, Timeout) -> Modifiers = case Reverse of true -> [<<"BYSCORE"/utf8>>, <<"REV"/utf8>>, <<"WITHSCORES"/utf8>>]; false -> [<<"BYSCORE"/utf8>>, <<"WITHSCORES"/utf8>>] end, _pipe = valkyrie@internal@commands:zrange( Key, numeric_bound_to_string(Start, fun score_to_string/1), numeric_bound_to_string(Stop, fun score_to_string/1), Modifiers ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_sorted_set_member_array/1). -file("src/valkyrie.gleam", 2129). ?DOC(false). -spec lex_bound_to_string(lex_bound()) -> binary(). lex_bound_to_string(Bound) -> case Bound of {lex_inclusive, Value} -> <<"["/utf8, Value/binary>>; {lex_exclusive, Value@1} -> <<"("/utf8, Value@1/binary>>; lex_positive_infinity -> <<"+"/utf8>>; lex_negative_infinity -> <<"-"/utf8>> end. -file("src/valkyrie.gleam", 2148). ?DOC( " Get a range of members from a sorted set by lexicographic order.\n" "\n" " When all members have the same score, this command returns members\n" " within the specified lexicographic range. Use `LexBound` to specify\n" " inclusive/exclusive bounds or infinity bounds.\n" "\n" " If `reverse` is `True`, returns members in reverse lexicographic order.\n" " Note: This only works correctly when all members have the same score.\n" "\n" " See the [Redis ZRANGE documentation](https://redis.io/commands/zrange) for more details.\n" ). -spec zrange_bylex( connection(), binary(), lex_bound(), lex_bound(), boolean(), integer() ) -> {ok, list(binary())} | {error, error()}. zrange_bylex(Conn, Key, Start, Stop, Reverse, Timeout) -> Modifiers = case Reverse of true -> [<<"BYLEX"/utf8>>, <<"REV"/utf8>>]; false -> [<<"BYLEX"/utf8>>] end, _pipe = valkyrie@internal@commands:zrange( Key, lex_bound_to_string(Start), lex_bound_to_string(Stop), Modifiers ), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 2176). ?DOC( " Get the rank (index) of a member in a sorted set.\n" "\n" " Returns the 0-based rank of the member, where 0 is the member with the lowest score.\n" " Returns `Error(NotFound)` if the key doesn't exist or the member is not in the set.\n" "\n" " See the [Redis ZRANK documentation](https://redis.io/commands/zrank) for more details.\n" ). -spec zrank(connection(), binary(), binary(), integer()) -> {ok, integer()} | {error, error()}. zrank(Conn, Key, Member, Timeout) -> _pipe = valkyrie@internal@commands:zrank(Key, Member), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_integer/1). -file("src/valkyrie.gleam", 2195). ?DOC( " Get the rank (index) and score of a member in a sorted set.\n" "\n" " Returns a tuple of `#(rank, score)` where rank is 0-based (lowest score = 0).\n" " Returns `Error(NotFound)` if the key doesn't exist or the member is not in the set.\n" "\n" " **Note:** This command is not supported by KeyDB.\n" "\n" " See the [Redis ZRANK documentation](https://redis.io/commands/zrank) for more details.\n" ). -spec zrank_withscore(connection(), binary(), binary(), integer()) -> {ok, {integer(), score()}} | {error, error()}. zrank_withscore(Conn, Key, Member, Timeout) -> _pipe = valkyrie@internal@commands:zrank_withscore(Key, Member), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_rank_and_score/1). -file("src/valkyrie.gleam", 2213). ?DOC( " Get the reverse rank (index) of a member in a sorted set.\n" "\n" " Returns the 0-based rank of the member in descending order, where 0 is the member\n" " with the highest score. Returns `Error(NotFound)` if the key doesn't exist or\n" " the member is not in the set.\n" "\n" " See the [Redis ZREVRANK documentation](https://redis.io/commands/zrevrank) for more details.\n" ). -spec zrevrank(connection(), binary(), binary(), integer()) -> {ok, integer()} | {error, error()}. zrevrank(Conn, Key, Member, Timeout) -> _pipe = valkyrie@internal@commands:zrevrank(Key, Member), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_integer/1). -file("src/valkyrie.gleam", 2233). ?DOC( " Get the reverse rank (index) and score of a member in a sorted set.\n" "\n" " Returns a tuple of `#(reverse_rank, score)` where reverse rank is 0-based in\n" " descending order (highest score = 0). Returns `Error(NotFound)` if the key\n" " doesn't exist or the member is not in the set.\n" "\n" " **Note:** This command is not supported by KeyDB.\n" "\n" " See the [Redis ZREVRANK documentation](https://redis.io/commands/zrevrank) for more details.\n" ). -spec zrevrank_withscore(connection(), binary(), binary(), integer()) -> {ok, {integer(), score()}} | {error, error()}. zrevrank_withscore(Conn, Key, Member, Timeout) -> _pipe = valkyrie@internal@commands:zrevrank_withscore(Key, Member), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_rank_and_score/1). -file("src/valkyrie.gleam", 2254). ?DOC( " Set field-value pairs in a hash.\n" "\n" " Creates the hash if it doesn't exist. Returns the number of fields that were\n" " added (not including fields that were updated with new values).\n" "\n" " See the [Redis HSET documentation](https://redis.io/commands/hset) for more details.\n" ). -spec hset( connection(), binary(), gleam@dict:dict(binary(), binary()), integer() ) -> {ok, integer()} | {error, error()}. hset(Conn, Key, Values, Timeout) -> _pipe = valkyrie@internal@commands:hset(Key, Values), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 2271). ?DOC( " Set a field in a hash, only if the field doesn't already exist.\n" "\n" " Returns `True` if the field was set, `False` if the field already exists.\n" " Creates the hash if it doesn't exist.\n" "\n" " See the [Redis HSETNX documentation](https://redis.io/commands/hsetnx) for more details.\n" ). -spec hsetnx(connection(), binary(), binary(), binary(), integer()) -> {ok, boolean()} | {error, error()}. hsetnx(Conn, Key, Field, Value, Timeout) -> _pipe = valkyrie@internal@commands:hsetnx(Key, Field, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 2288). ?DOC( " Get the number of fields in a hash.\n" "\n" " Returns 0 if the key doesn't exist.\n" "\n" " See the [Redis HLEN documentation](https://redis.io/commands/hlen) for more details.\n" ). -spec hlen(connection(), binary(), integer()) -> {ok, integer()} | {error, error()}. hlen(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:hlen(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 2299). ?DOC( " Get all field names in a hash.\n" "\n" " Returns an empty list if the key doesn't exist.\n" "\n" " See the [Redis HKEYS documentation](https://redis.io/commands/hkeys) for more details.\n" ). -spec hkeys(connection(), binary(), integer()) -> {ok, list(binary())} | {error, error()}. hkeys(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:hkeys(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 2314). ?DOC( " Get the value of a field in a hash.\n" "\n" " Returns `Error(NotFound)` if the key doesn't exist or the field doesn't exist.\n" "\n" " See the [Redis HGET documentation](https://redis.io/commands/hget) for more details.\n" ). -spec hget(connection(), binary(), binary(), integer()) -> {ok, binary()} | {error, error()}. hget(Conn, Key, Field, Timeout) -> _pipe = valkyrie@internal@commands:hget(Key, Field), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_bulk_string/1). -file("src/valkyrie.gleam", 2332). ?DOC( " Get all field-value pairs in a hash.\n" "\n" " Returns an empty dictionary if the key doesn't exist.\n" "\n" " **Note:** The return type uses raw `resp.Value` types. This may change in future versions.\n" "\n" " See the [Redis HGETALL documentation](https://redis.io/commands/hgetall) for more details.\n" ). -spec hgetall(connection(), binary(), integer()) -> {ok, gleam@dict:dict(valkyrie@resp:value(), valkyrie@resp:value())} | {error, error()}. hgetall(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:hgetall(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_map/1). -file("src/valkyrie.gleam", 2348). ?DOC( " Get the values of multiple fields in a hash.\n" "\n" " Returns a list of `Result(String, Error)` values. The value will be\n" " `Error(NotFound)` if the field doesn't exist.\n" "\n" " See the [Redis HMGET documentation](https://redis.io/commands/hmget) for more details.\n" ). -spec hmget(connection(), binary(), list(binary()), integer()) -> {ok, list({ok, binary()} | {error, error()})} | {error, error()}. hmget(Conn, Key, Fields, Timeout) -> _pipe = valkyrie@internal@commands:hmget(Key, Fields), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_nullable_bulk_string_array/1). -file("src/valkyrie.gleam", 2364). ?DOC( " Get the string length of a field's value in a hash.\n" "\n" " Returns 0 if the key doesn't exist or the field doesn't exist.\n" "\n" " See the [Redis HSTRLEN documentation](https://redis.io/commands/hstrlen) for more details.\n" ). -spec hstrlen(connection(), binary(), binary(), integer()) -> {ok, integer()} | {error, error()}. hstrlen(Conn, Key, Field, Timeout) -> _pipe = valkyrie@internal@commands:hstrlen(Key, Field), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 2380). ?DOC( " Get all values in a hash.\n" "\n" " Returns an empty list if the key doesn't exist.\n" "\n" " See the [Redis HVALS documentation](https://redis.io/commands/hvals) for more details.\n" ). -spec hvals(connection(), binary(), integer()) -> {ok, list(binary())} | {error, error()}. hvals(Conn, Key, Timeout) -> _pipe = valkyrie@internal@commands:hvals(Key), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_bulk_string_array/1). -file("src/valkyrie.gleam", 2396). ?DOC( " Delete one or more fields from a hash.\n" "\n" " Returns the number of fields that were actually removed from the hash\n" " (not including fields that didn't exist).\n" "\n" " See the [Redis HDEL documentation](https://redis.io/commands/hdel) for more details.\n" ). -spec hdel(connection(), binary(), list(binary()), integer()) -> {ok, integer()} | {error, error()}. hdel(Conn, Key, Fields, Timeout) -> _pipe = valkyrie@internal@commands:hdel(Key, Fields), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 2413). ?DOC( " Check if a field exists in a hash.\n" "\n" " Returns `True` if the field exists, `False` otherwise.\n" " Returns `False` if the key doesn't exist.\n" "\n" " See the [Redis HEXISTS documentation](https://redis.io/commands/hexists) for more details.\n" ). -spec hexists(connection(), binary(), binary(), integer()) -> {ok, boolean()} | {error, error()}. hexists(Conn, Key, Field, Timeout) -> _pipe = valkyrie@internal@commands:hexists(Key, Field), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer_boolean/1). -file("src/valkyrie.gleam", 2430). ?DOC( " Increment the integer value of a field in a hash by the given amount.\n" "\n" " If the field doesn't exist, it's set to 0 before incrementing.\n" " Creates the hash if it doesn't exist. Returns the new value after incrementing.\n" "\n" " See the [Redis HINCRBY documentation](https://redis.io/commands/hincrby) for more details.\n" ). -spec hincrby(connection(), binary(), binary(), integer(), integer()) -> {ok, integer()} | {error, error()}. hincrby(Conn, Key, Field, Value, Timeout) -> _pipe = valkyrie@internal@commands:hincrby(Key, Field, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_integer/1). -file("src/valkyrie.gleam", 2448). ?DOC( " Increment the floating point value of a field in a hash by the given amount.\n" "\n" " If the field doesn't exist, it's set to 0 before incrementing.\n" " Creates the hash if it doesn't exist. Returns the new value after incrementing.\n" "\n" " See the [Redis HINCRBYFLOAT documentation](https://redis.io/commands/hincrbyfloat) for more details.\n" ). -spec hincrbyfloat(connection(), binary(), binary(), float(), integer()) -> {ok, float()} | {error, error()}. hincrbyfloat(Conn, Key, Field, Value, Timeout) -> _pipe = valkyrie@internal@commands:hincrbyfloat(Key, Field, Value), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_float/1). -file("src/valkyrie.gleam", 2469). ?DOC( " Iterate incrementally over field-value pairs in a hash.\n" "\n" " Returns a tuple of `#(field_value_pairs, next_cursor)`. Use the returned cursor\n" " for subsequent calls. A cursor of 0 indicates the end of iteration.\n" "\n" " This is the recommended way to iterate over large hashes in production\n" " environments.\n" "\n" " See the [Redis HSCAN documentation](https://redis.io/commands/hscan) for more details.\n" ). -spec hscan( connection(), binary(), integer(), gleam@option:option(binary()), integer(), integer() ) -> {ok, {list({binary(), binary()}), integer()}} | {error, error()}. hscan(Conn, Key, Cursor, Pattern_filter, Count, Timeout) -> _pipe = valkyrie@internal@commands:hscan(Key, Cursor, Pattern_filter, Count), _pipe@1 = execute(Conn, _pipe, Timeout), gleam@result:'try'(_pipe@1, fun expect_cursor_and_hash_field_array/1). -file("src/valkyrie.gleam", 230). -spec create_socket(config(), integer()) -> {ok, mug:socket()} | {error, error()}. create_socket(Config, Timeout) -> gleam@result:'try'( begin _pipe = mug:new( erlang:element(2, Config), erlang:element(3, Config) ), _pipe@1 = mug:ip_version_preference( _pipe, erlang:element(5, Config) ), _pipe@2 = mug:timeout(_pipe@1, Timeout), _pipe@3 = mug:connect(_pipe@2), gleam@result:map_error( _pipe@3, fun(Field@0) -> {connect_error, Field@0} end ) end, fun(Socket) -> Conn = {single, Socket}, gleam@result:'try'( execute( Conn, [<<"HELLO"/utf8>>, erlang:integer_to_binary(3) | auth_to_options_list(erlang:element(4, Config))], Timeout ), fun(_) -> {ok, Socket} end ) end ). -file("src/valkyrie.gleam", 262). ?DOC( " Create a single Redis connection.\n" "\n" " This will attempt to authenticate with Redis using the provided configuration via\n" " the `HELLO 3` command. See the documentation on [`supervised_pool`](#supervised_pool)\n" " for more information on how to use connections in Valkyrie. The API is the same for\n" " using single connections and supervised pools.\n" "\n" " This establishes a direct connection to Redis using the provided configuration.\n" " For high-throughput applications, consider using [`supervised_pool`](#supervised_pool).\n" ). -spec create_connection(config(), integer()) -> {ok, connection()} | {error, error()}. create_connection(Config, Timeout) -> _pipe = create_socket(Config, Timeout), gleam@result:map(_pipe, fun(Field@0) -> {single, Field@0} end). -file("src/valkyrie.gleam", 270). -spec create_pool_builder( config(), integer(), integer(), gleam@option:option(gleam@erlang@process:name(bath:msg(mug:socket()))) ) -> bath:builder(mug:socket()). create_pool_builder(Config, Pool_size, Init_timeout, Pool_name) -> Pool_builder = begin _pipe@1 = bath:new(fun() -> _pipe = create_socket(Config, Init_timeout), gleam@result:map_error(_pipe, fun error_to_string/1) end), _pipe@2 = bath:size(_pipe@1, Pool_size), bath:on_shutdown( _pipe@2, fun(Socket) -> _pipe@3 = mug_ffi:shutdown(Socket), gleam@result:unwrap(_pipe@3, nil) end ) end, case Pool_name of {some, Name} -> bath:name(Pool_builder, Name); none -> Pool_builder end. -file("src/valkyrie.gleam", 303). ?DOC( " Start a connection pool for Redis connections.\n" "\n" " This function will `PING` your Redis instance once to ensure it is reachable.\n" " Further information about how to use the connection pool can be found in the\n" " documentation for [`supervised_pool`](#supervised_pool).\n" "\n" " Consider using [`supervised_pool`](#supervised_pool) instead, which\n" " provides automatic restart capabilities and better integration with OTP supervision\n" " trees. This function should only be used when you need to manage the pool lifecycle\n" " manually.\n" ). -spec start_pool( config(), integer(), gleam@option:option(gleam@erlang@process:name(bath:msg(mug:socket()))), integer() ) -> {ok, connection()} | {error, start_error()}. start_pool(Config, Pool_size, Pool_name, Init_timeout) -> gleam@result:'try'( begin _pipe = create_pool_builder( Config, Pool_size, Init_timeout, Pool_name ), _pipe@1 = bath:start(_pipe, Init_timeout), _pipe@2 = gleam@result:map( _pipe@1, fun(Field@0) -> {pooled, Field@0} end ), gleam@result:map_error( _pipe@2, fun(Field@0) -> {actor_start_error, Field@0} end ) end, fun(Pool) -> _pipe@3 = ping(Pool, none, 1000), _pipe@4 = gleam@result:replace(_pipe@3, Pool), gleam@result:map_error( _pipe@4, fun(Field@0) -> {ping_error, Field@0} end ) end ). -file("src/valkyrie.gleam", 375). ?DOC( " Create a supervised connection pool for Redis connections.\n" "\n" " Returns a supervision specification for including the pool into your\n" " supervision tree. The pool will be automatically restarted if it crashes,\n" " making this the recommended approach for production applications.\n" "\n" " If you wish to use the supervised pool under a static supervisor, you _must_\n" " provide a name, or you'll have no\n" "\n" " Connections are created lazily when requested from the pool. On creation,\n" " connections will call `HELLO 3` with any authentication information to authenticate\n" " with the Redis-compatible server. No additional commands will be sent.\n" "\n" " The [`Connection`](#Connection) value will be sent to the provided subject\n" " when the pool is started.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " import gleam/erlang/process\n" " import gleam/option\n" " import gleam/otp/static_supervisor as supervisor\n" " import valkyrie\n" "\n" " pub fn main() {\n" " // Create a name to interact with the connection pool once it's started under the\n" " // static supervisor.\n" " let pool_name = process.new_name(\"connection_pool\")\n" "\n" " // Define a pool of 10 connections to the default Redis instance on localhost.\n" " let valkyrie_child_spec =\n" " valkyrie.default_config()\n" " |> valkyrie.supervised_pool(\n" " size: 10,\n" " name: option.Some(pool_name),\n" " timeout: 1000,\n" " )\n" "\n" " // Start the pool under a supervisor\n" " let assert Ok(_started) =\n" " supervisor.new(supervisor.OneForOne)\n" " |> supervisor.add(valkyrie_child_spec)\n" " |> supervisor.start\n" "\n" " // Get the connection now that the pool is started\n" " let conn = valkyrie.named_connection(pool_name)\n" "\n" " // Use the connection.\n" " let assert Ok(_) = echo valkyrie.set(conn, \"key\", \"value\", option.None, 1000)\n" " let assert Ok(_) = echo valkyrie.get(conn, \"key\", 1000)\n" "\n" " // Do more stuff...\n" " }\n" " ```\n" ). -spec supervised_pool( config(), integer(), gleam@option:option(gleam@erlang@process:name(bath:msg(mug:socket()))), integer() ) -> gleam@otp@supervision:child_specification(connection()). supervised_pool(Config, Pool_size, Pool_name, Init_timeout) -> _pipe = create_pool_builder(Config, Pool_size, Init_timeout, Pool_name), _pipe@1 = bath:supervised(_pipe, Init_timeout), gleam@otp@supervision:map_data( _pipe@1, fun(Field@0) -> {pooled, Field@0} end ). -file("src/valkyrie.gleam", 111). ?DOC( " Create a default Redis configuration.\n" "\n" " Returns a configuration with:\n" " - host: `\"localhost\"`\n" " - port: `6379`\n" " - auth: `NoAuth`\n" " - ip_version_preference: `mug.Ipv6Preferred`\n" ). -spec default_config() -> config(). default_config() -> {config, <<"localhost"/utf8>>, 6379, no_auth, ipv6_preferred}. -file("src/valkyrie.gleam", 177). ?DOC( " Parse a Redis-compatible URI into a Config object.\n" "\n" " Supports the following protocols:\n" " - `redis://`\n" " - `valkey://`\n" " - `keydb://`\n" "\n" " URI format: `protocol://[username:password@]host[:port][/database]`\n" "\n" " The database path in the URI is ignored but won't cause an error.\n" " If no port is specified, defaults to 6379.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // Basic usage\n" " let assert Ok(config) = url_config(\"redis://localhost:6379\")\n" " // Config(host: \"localhost\", port: 6379, auth: NoAuth)\n" "\n" " // With authentication\n" " let assert Ok(config) = url_config(\"redis://user:pass@localhost:6379\")\n" " // Config(host: \"localhost\", port: 6379, auth: UsernameAndPassword(\"user\", \"pass\"))\n" "\n" " // Password-only authentication\n" " let assert Ok(config) = url_config(\"redis://:mypassword@localhost:6379\")\n" " // Config(host: \"localhost\", port: 6379, auth: PasswordOnly(\"mypassword\"))\n" " ```\n" ). -spec url_config(binary()) -> {ok, config()} | {error, url_parse_error()}. url_config(Url) -> gleam@result:'try'( begin _pipe = gleam_stdlib:uri_parse(Url), gleam@result:replace_error(_pipe, invalid_uri_format) end, fun(Parsed_uri) -> gleam@result:'try'(case erlang:element(2, Parsed_uri) of {some, <<"redis"/utf8>>} -> {ok, erlang:element(2, Parsed_uri)}; {some, <<"valkey"/utf8>>} -> {ok, erlang:element(2, Parsed_uri)}; {some, <<"keydb"/utf8>>} -> {ok, erlang:element(2, Parsed_uri)}; {some, _} -> {error, unsupported_scheme}; none -> {error, missing_scheme} end, fun(_) -> gleam@result:'try'(case erlang:element(4, Parsed_uri) of {some, <<""/utf8>>} -> {error, missing_host}; none -> {error, missing_host}; {some, H} -> {ok, H} end, fun(Host) -> Port = case erlang:element(5, Parsed_uri) of {some, P} -> P; none -> 6379 end, Auth = case erlang:element(3, Parsed_uri) of {some, Userinfo} -> case gleam@string:split( Userinfo, <<":"/utf8>> ) of [<<""/utf8>>, Password] -> {password_only, Password}; [Username, Password@1] -> {username_and_password, Username, Password@1}; [Password@2] -> {password_only, Password@2}; [] -> no_auth; _ -> no_auth end; none -> no_auth end, {ok, {config, Host, Port, Auth, ipv6_preferred}} end) end) end ).