redis

    Async Redis client for MoonBit, built on `moonbitlang/async`.

    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    4 months ago
    Downloads
    43

    Dependencies

    #hackwaly/redis

    Async Redis client for MoonBit, built on moonbitlang/async.

    The client supports common Redis commands, typed response decoding, transactions, automatic pipelining from concurrent calls, raw commands, and RESP2 pub/sub.

    #Features

    • Async Redis client built on moonbitlang/async
    • RESP3 command connections with RESP2 fallback
    • Typed helpers for strings, keys, hashes, lists, sets, and sorted sets
    • Automatic pipelining for concurrent commands on the same Client
    • Transactions with WATCH, MULTI, and EXEC
    • Raw commands through Command
    • Pub/sub with typed channel and pattern messages
    • Configurable authentication, database selection, timeouts, reconnect strategy, and command queue bounds
    • Typed client errors for server, transport, protocol, decoding, overflow, and worker-state failures

    #Installation

    Add the package to your MoonBit project:

    moon add hackwaly/redis

    Then import it from your package's moon.pkg:

    import {
    "hackwaly/redis"
    }

    #Quick Start

    Regular commands run through a background worker. Start client.work() in a task group, issue commands on the same Client, and cancel the worker when the client is no longer needed.

    ///|
    pub async fn quick_start() -> Unit {
    @async.with_task_group(group => {
    let client = @redis.Client(
    config=@redis.ClientConfig(host="127.0.0.1", port=6379),
    )
    let worker = group.spawn(() => client.work(), allow_failure=true)
    defer worker.cancel()

    assert_true(client.ping() == "PONG")
    assert_true(client.set("moonbit:redis:hello", "world"))
    assert_true(client.get("moonbit:redis:hello") is Some("world"))
    })
    }

    Command connections try RESP3 first and fall back to RESP2 when the server does not support HELLO 3.

    #Configuration

    ClientConfig controls connection, authentication, database selection, timeouts, reconnect behavior, and command queue bounds.

    ///|
    pub fn example_config() -> @redis.ClientConfig {
    @redis.ClientConfig(
    host="127.0.0.1",
    port=6379,
    username="default",
    password="secret",
    database=0,
    name="moonbit-app",
    command_queue_max_length=1024,
    )
    }

    #Commands

    The client exposes typed helpers for Redis strings, keys, hashes, lists, sets, sorted sets, scanning, and related commands.

    ///|
    pub async fn command_examples(client : @redis.Client) -> Unit {
    assert_true(client.set("counter", "1"))
    assert_true(client.incr("counter") == 2)
    assert_true(client.mget(["counter", "missing"]) is [Some("2"), None])

    assert_true(client.hset("user:1", "name", "MoonBit") == 1)
    assert_true(client.hget("user:1", "name") is Some("MoonBit"))
    }

    Use Client::execute with Command for raw commands not covered by a helper:

    ///|
    pub async fn raw_command_example(client : @redis.Client) -> String {
    client.execute(@redis.Command([b"PING"], value => value.as_string()))
    }

    #Automatic Pipelining

    Like node-redis Promise.all, this client automatically pipelines commands that are issued concurrently on the same Client. Each call is queued, the worker writes commands to the connection in order, and responses are matched back to their waiting tasks.

    ///|
    pub async fn auto_pipeline_example(
    client : @redis.Client,
    ) -> (String?, String?, Int) {
    @async.with_task_group(group => {
    let first = group.spawn(() => client.get("key:1"))
    let second = group.spawn(() => client.get("key:2"))
    let count = group.spawn(() => client.exists(["key:1", "key:2"]))

    (first.wait(), second.wait(), count.wait())
    })
    }

    There is no separate pipeline object for this behavior. Use concurrent async contexts when you want multiple independent commands to share one connection round trip pattern.

    #Transactions

    Transactions use Client::transaction, Transaction::watch, Multi, and MultiResult::get.

    ///|
    pub async fn transaction_example(client : @redis.Client) -> Unit {
    client.transaction(tx => {
    tx.watch(["account:1"])

    let multi = @redis.Multi()
    let old_value = multi.get("account:1")
    let wrote = multi.set("account:1", "updated")

    guard tx.exec(multi) is Some(result) else {
    fail("transaction was aborted")
    }
    ignore(result.get(old_value))
    assert_true(result.get(wrote))
    })
    }

    If watched keys are modified before EXEC, tx.exec(multi) returns None. Errors for individual queued commands are raised when reading that token with MultiResult::get.

    #Pub/Sub

    Pub/sub callbacks receive typed channel or pattern messages. Run subscriptions in their own async task and cancel that task when you want to stop receiving messages.

    ///|
    pub async fn pubsub_example() -> Unit {
    @async.with_task_group(group => {
    let publisher = @redis.Client(
    config=@redis.ClientConfig(host="127.0.0.1", port=6379),
    )
    let publisher_worker = group.spawn(
    () => publisher.work(),
    allow_failure=true,
    )
    defer publisher_worker.cancel()

    let subscriber = @redis.Client(
    config=@redis.ClientConfig(host="127.0.0.1", port=6379),
    )
    let received = group.spawn(
    () => {
    subscriber.subscribe("events", msg => {
    assert_true(msg.channel == "events")
    assert_true(msg.payload.text() == "hello")
    })
    },
    allow_failure=true,
    )

    ignore(publisher.publish("events", "hello"))
    received.cancel()
    })
    }

    subscribe and psubscribe are long-running operations. Cancel the task that runs the subscription when you want to stop receiving messages.

    #Error Handling

    Redis server errors are raised as ServerError. Protocol shape mismatches, invalid UTF-8, integer overflow, transport failures, handshake failures, and concurrent worker misuse are reported with ClientError variants:

    ///|
    pub async fn handle_error(client : @redis.Client) -> Unit {
    try client.get("key") catch {
    @redis.ServerError(message) => println("Redis error: \{message}")
    _ => println("Client error")
    } noraise {
    _ => ()
    }
    }

    #Roadmap

    The roadmap is non-binding and describes possible future work:

    • Pub/sub over RESP3 push messages multiplexed on the main client connection
    • Connection pooling for workloads that need multiple independent Redis connections
    • Broader command coverage, especially Redis Streams and scripting helpers
    • More pub/sub ergonomics around cancellation and subscription lifecycle
    • Improved README and API examples as MoonBit package documentation evolves
    • Possible Redis Cluster or Sentinel support later

    #Testing

    Run unit tests:

    moon test

    Run Redis integration tests with Docker:

    ./scripts/redis-integration-test.sh

    The integration script starts redis:7-alpine on 127.0.0.1:6380 and runs the integration package against it.

    #License

    Apache-2.0

    ClientError

    pub suberror ClientError {
    ServerError(String)
    TransportError(Error)
    HandshakeError(String)
    UnexpectedResponse(String)
    InvalidUtf8(Bytes)
    IntegerOverflow(Int64)
    ClientAlreadyWorking
    }

    Errors raised by this Redis client.

    Server-side Redis errors are reported as ServerError. Other variants cover connection setup, transport, response decoding, and client lifecycle misuse.

    Example:
    try client.get("key") catch {
    @redis.ServerError(message) => println(message)
    @redis.ClientAlreadyWorking => println("client is already running")
    _ => println("redis client error")
    } noraise {
    _ => ()
    }

    Client

    pub struct Client {
    // private fields
    }
    fn Client::Client(config? : ClientConfig) -> Client

    Redis client.

    Create one with Client::Client, run Client::work in a background async task, then call command methods such as get, set, or publish from other tasks.

    Example:
    @async.with_task_group(group => {
    let client = @redis.Client()
    let worker = group.spawn(() => client.work(), allow_failure=true)
    defer worker.cancel()

    ignore(client.ping())
    })

    Client::append

    async fn Client::append(self : Client, key : String, value : String) -> Int

    Client::decr

    async fn Client::decr(self : Client, key : String) -> Int

    Client::decrby

    async fn Client::decrby(self : Client, key : String, decrement : Int) -> Int

    Client::del

    async fn Client::del(self : Client, keys : ArrayView[String]) -> Int

    Client::echo

    async fn Client::echo(self : Client, message : String) -> String

    Client::execute

    async fn[T] Client::execute(self : Client, cmd : Command[T]) -> T

    Runs a custom Redis command through this client.

    Use this when the package does not provide a typed helper for the command you need. The command's decoder decides the result type and may raise if the Redis response has an unexpected shape.

    Example:
    let pong = client.execute(@redis.Command([b"PING"], value => value.as_string()))

    Client::exists

    async fn Client::exists(self : Client, keys : ArrayView[String]) -> Int

    Client::expire

    async fn Client::expire(self : Client, key : String, seconds : Int) -> Bool

    Client::get

    async fn Client::get(self : Client, key : String) -> String?

    Reads a string value. Returns None when the key does not exist.

    Example:
    assert_true(client.get("missing") is None)

    Client::getrange

    async fn Client::getrange(self : Client, key : String, start : Int, end : Int) -> String

    Client::hdel

    async fn Client::hdel(self : Client, key : String, fields : ArrayView[String]) -> Int

    Client::hexists

    async fn Client::hexists(self : Client, key : String, field : String) -> Bool

    Client::hget

    async fn Client::hget(self : Client, key : String, field : String) -> String?

    Reads a hash field. Returns None when the key or field does not exist.

    Example:
    assert_true(client.hget("user:1", "name") is Some("MoonBit"))

    Client::hgetall

    async fn Client::hgetall(self : Client, key : String) -> Map[String, String]

    Reads all fields from a hash as a map.

    Example:
    let fields = client.hgetall("user:1")

    Client::hincrby

    async fn Client::hincrby(self : Client, key : String, field : String, increment : Int) -> Int

    Client::hincrbyfloat

    async fn Client::hincrbyfloat(self : Client, key : String, field : String, increment : Double) -> Double

    Client::hkeys

    async fn Client::hkeys(self : Client, key : String) -> Array[String]

    Client::hlen

    async fn Client::hlen(self : Client, key : String) -> Int

    Client::hmget

    async fn Client::hmget(self : Client, key : String, fields : ArrayView[String]) -> Array[String?]

    Client::hmset

    async fn Client::hmset(self : Client, key : String, fields : ArrayView[(String, String)]) -> Unit

    Client::hscan

    async fn Client::hscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Map[String, String])

    Client::hset

    async fn Client::hset(self : Client, key : String, field : String, value : String) -> Int

    Sets a hash field and returns the number of fields newly added.

    Example:
    ignore(client.hset("user:1", "name", "MoonBit"))

    Client::hstrlen

    async fn Client::hstrlen(self : Client, key : String, field : String) -> Int

    Client::hvals

    async fn Client::hvals(self : Client, key : String) -> Array[String]

    Client::incr

    async fn Client::incr(self : Client, key : String) -> Int

    Increments an integer string value by one and returns the new value.

    Example:
    ignore(client.set("count", "1"))
    assert_true(client.incr("count") == 2)

    Client::incrby

    async fn Client::incrby(self : Client, key : String, increment : Int) -> Int

    Client::incrbyfloat

    async fn Client::incrbyfloat(self : Client, key : String, increment : Double) -> Double

    Client::keys

    async fn Client::keys(self : Client, pattern : String) -> Array[String]

    Client::lindex

    async fn Client::lindex(self : Client, key : String, index : Int) -> String?

    Client::linsert_after

    async fn Client::linsert_after(self : Client, key : String, pivot : String, value : String) -> Int

    Client::linsert_before

    async fn Client::linsert_before(self : Client, key : String, pivot : String, value : String) -> Int

    Client::llen

    async fn Client::llen(self : Client, key : String) -> Int

    Client::lpop

    async fn Client::lpop(self : Client, key : String) -> String?

    Client::lpop_count

    async fn Client::lpop_count(self : Client, key : String, count : Int) -> Array[String]

    Client::lpush

    async fn Client::lpush(self : Client, key : String, values : ArrayView[String]) -> Int

    Pushes values to the left side of a list and returns the new list length.

    Example:
    ignore(client.lpush("jobs", ["a", "b"]))

    Client::lrange

    async fn Client::lrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

    Reads a range from a list.

    Example:
    let values = client.lrange("jobs", 0, -1)

    Client::lrem

    async fn Client::lrem(self : Client, key : String, count : Int, value : String) -> Int

    Client::lset

    async fn Client::lset(self : Client, key : String, index : Int, value : String) -> Unit

    Client::ltrim

    async fn Client::ltrim(self : Client, key : String, start : Int, stop : Int) -> Unit

    Client::mget

    async fn Client::mget(self : Client, keys : ArrayView[String]) -> Array[String?]

    Reads multiple string values in the same order as keys.

    Missing keys are returned as None.

    Example:
    let values = client.mget(["name", "missing"])
    assert_true(values is [Some("MoonBit"), None])

    Client::mset

    async fn Client::mset(self : Client, items : ArrayView[(String, String)]) -> Unit

    Client::msetnx

    async fn Client::msetnx(self : Client, items : ArrayView[(String, String)]) -> Bool

    Client::persist

    async fn Client::persist(self : Client, key : String) -> Bool

    Client::pexpire

    async fn Client::pexpire(self : Client, key : String, milliseconds : Int) -> Bool

    Client::ping

    async fn Client::ping(self : Client, message? : String) -> String

    Checks that Redis is reachable.

    Example:
    assert_true(client.ping() == "PONG")
    assert_true(client.ping(message="hello") == "hello")

    Client::psetex

    async fn Client::psetex(self : Client, key : String, milliseconds : Int, value : String) -> Unit

    Client::psubscribe

    async fn Client::psubscribe(self : Client, pattern : String, callback : async (PatternMessage) -> Unit) -> Unit

    Pattern-subscribes and invokes callback for each matching message.

    This is a long-running operation. Run it in its own async task and cancel that task to stop receiving messages.

    Example:
    group.spawn(() => {
    client.psubscribe("events:*", msg => {
    println(msg.channel)
    })
    }, allow_failure=true)

    Client::pttl

    async fn Client::pttl(self : Client, key : String) -> Int

    Client::publish

    async fn Client::publish(self : Client, channel : String, payload : &
    Data
    ) -> Int

    Publishes payload to channel and returns the number of subscribers that received the message.

    Example:
    let receivers = client.publish("events", "hello")

    Client::randomkey

    async fn Client::randomkey(self : Client) -> String?

    Client::rename

    async fn Client::rename(self : Client, key : String, new_key : String) -> Unit

    Client::renamenx

    async fn Client::renamenx(self : Client, key : String, new_key : String) -> Bool

    Client::rpop

    async fn Client::rpop(self : Client, key : String) -> String?

    Client::rpop_count

    async fn Client::rpop_count(self : Client, key : String, count : Int) -> Array[String]

    Client::rpush

    async fn Client::rpush(self : Client, key : String, values : ArrayView[String]) -> Int

    Client::sadd

    async fn Client::sadd(self : Client, key : String, members : ArrayView[String]) -> Int

    Adds members to a set and returns the number of members newly added.

    Example:
    ignore(client.sadd("tags", ["moonbit", "redis"]))

    Client::scan

    async fn Client::scan(self : Client, cursor : String, pattern? : String, count? : Int) -> (String, Array[String])

    Client::scard

    async fn Client::scard(self : Client, key : String) -> Int

    Client::sdiff

    async fn Client::sdiff(self : Client, keys : ArrayView[String]) ->
    HashSet
    [String]

    Client::sdiffstore

    async fn Client::sdiffstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

    Client::set

    async fn Client::set(self : Client, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> Bool

    Sets a string value.

    Returns false when nx or xx prevents the write.

    Example:
    assert_true(client.set("name", "MoonBit"))
    assert_true(client.set("token", "abc", ex=60, nx=true))

    Client::set_get

    async fn Client::set_get(self : Client, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> String?

    Client::setex

    async fn Client::setex(self : Client, key : String, seconds : Int, value : String) -> Unit

    Client::setnx

    async fn Client::setnx(self : Client, key : String, value : String) -> Bool

    Client::setrange

    async fn Client::setrange(self : Client, key : String, offset : Int, value : String) -> Int

    Client::sinter

    async fn Client::sinter(self : Client, keys : ArrayView[String]) ->
    HashSet
    [String]

    Client::sinterstore

    async fn Client::sinterstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

    Client::sismember

    async fn Client::sismember(self : Client, key : String, value : String) -> Bool

    Client::smembers

    async fn Client::smembers(self : Client, key : String) ->
    HashSet
    [String]

    Reads all members of a set.

    Example:
    let members = client.smembers("tags")

    Client::smismember

    async fn Client::smismember(self : Client, key : String, members : ArrayView[String]) -> Array[Bool]

    Client::smove

    async fn Client::smove(self : Client, source : String, destination : String, value : String) -> Bool

    Client::spop

    async fn Client::spop(self : Client, key : String) -> String?

    Client::spop_count

    async fn Client::spop_count(self : Client, key : String, count : Int) ->
    HashSet
    [String]

    Client::srandmember

    async fn Client::srandmember(self : Client, key : String) -> String?

    Client::srandmember_count

    async fn Client::srandmember_count(self : Client, key : String, count : Int) -> Array[String]

    Client::srem

    async fn Client::srem(self : Client, key : String, members : ArrayView[String]) -> Int

    Client::sscan

    async fn Client::sscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String,
    HashSet
    [String])

    Client::strlen

    async fn Client::strlen(self : Client, key : String) -> Int

    Client::subscribe

    async fn Client::subscribe(self : Client, channel : String, callback : async (Message) -> Unit) -> Unit

    Subscribes to one channel and invokes callback for each received message.

    This is a long-running operation. Run it in its own async task and cancel that task to stop receiving messages.

    Example:
    group.spawn(() => {
    client.subscribe("events", msg => {
    println(msg.payload.text())
    })
    }, allow_failure=true)

    Client::sunion

    async fn Client::sunion(self : Client, keys : ArrayView[String]) ->
    HashSet
    [String]

    Client::sunionstore

    async fn Client::sunionstore(self : Client, destination : String, keys : ArrayView[String]) -> Int

    Client::transaction

    async fn[T] Client::transaction(self : Client, f : async (Transaction) -> T) -> T

    Runs a callback in a Redis transaction session.

    Use Transaction::watch before building a Multi when optimistic locking is needed. The returned value is whatever the callback returns.

    Example:
    client.transaction(tx => {
    tx.watch(["account:1"])
    let multi = @redis.Multi()
    let wrote = multi.set("account:1", "updated")

    guard tx.exec(multi) is Some(result) else {
    fail("transaction aborted")
    }
    result.get(wrote)
    })

    Client::ttl

    async fn Client::ttl(self : Client, key : String) -> Int

    Client::type_

    async fn Client::type_(self : Client, key : String) -> String

    Client::work

    async fn Client::work(self : Client) -> Unit

    Keeps the regular command connection running.

    A client may have at most one active work loop. Start a new Client if you need another independent Redis connection. Cancelling the task running work is the normal way to stop the client.

    Example:
    @async.with_task_group(group => {
    let client = @redis.Client()
    let worker = group.spawn(() => client.work(), allow_failure=true)
    defer worker.cancel()

    assert_true(client.set("hello", "world"))
    })

    Client::zadd

    async fn Client::zadd(self : Client, key : String, items : ArrayView[(String, Double)]) -> Int

    Adds members with scores to a sorted set.

    Example:
    ignore(client.zadd("rank", [("alice", 10.0), ("bob", 8.0)]))

    Client::zcard

    async fn Client::zcard(self : Client, key : String) -> Int

    Client::zcount

    async fn Client::zcount(self : Client, key : String, min : Double, max : Double) -> Int

    Client::zincrby

    async fn Client::zincrby(self : Client, key : String, increment : Double, value : String) -> Double

    Client::zpopmax

    async fn Client::zpopmax(self : Client, key : String, count? : Int) -> Array[(String, Double)]

    Client::zpopmin

    async fn Client::zpopmin(self : Client, key : String, count? : Int) -> Array[(String, Double)]

    Client::zrange

    async fn Client::zrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

    Reads sorted set members by rank.

    Example:
    let top = client.zrange("rank", 0, 9)

    Client::zrange_with_scores

    async fn Client::zrange_with_scores(self : Client, key : String, start : Int, stop : Int) -> Array[(String, Double)]

    Client::zrangebyscore

    async fn Client::zrangebyscore(self : Client, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[String]

    Client::zrangebyscore_with_scores

    async fn Client::zrangebyscore_with_scores(self : Client, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[(String, Double)]

    Client::zrank

    async fn Client::zrank(self : Client, key : String, value : String) -> Int?

    Client::zrem

    async fn Client::zrem(self : Client, key : String, members : ArrayView[String]) -> Int

    Client::zremrangebyrank

    async fn Client::zremrangebyrank(self : Client, key : String, start : Int, stop : Int) -> Int

    Client::zremrangebyscore

    async fn Client::zremrangebyscore(self : Client, key : String, min : Double, max : Double) -> Int

    Client::zrevrange

    async fn Client::zrevrange(self : Client, key : String, start : Int, stop : Int) -> Array[String]

    Client::zrevrange_with_scores

    async fn Client::zrevrange_with_scores(self : Client, key : String, start : Int, stop : Int) -> Array[(String, Double)]

    Client::zrevrank

    async fn Client::zrevrank(self : Client, key : String, value : String) -> Int?

    Client::zscan

    async fn Client::zscan(self : Client, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Array[(String, Double)])

    Client::zscore

    async fn Client::zscore(self : Client, key : String, value : String) -> Double?

    ClientConfig

    pub struct ClientConfig {
    name : String?
    host : String
    port : Int
    username : String
    password : String?
    database : Int
    read_buffer_size : Int
    write_buffer_size : Int
    resp_max_depth : Int
    connect_timeout : Double
    reconnect_strategy :
    RetryMethod

    command_queue_max_length : Int?
    }
    fn ClientConfig::ClientConfig(name? : String, host? : String, port? : Int, username? : String, password? : String, database? : Int, read_buffer_size? : Int, write_buffer_size? : Int, resp_max_depth? : Int, connect_timeout? : Double, reconnect_strategy? :
    RetryMethod
    , command_queue_max_length? : Int) -> ClientConfig

    Connection and runtime options for Client.

    The default configuration connects to 127.0.0.1:6379, authenticates as the Redis default user when a password is provided, uses database 0, and retries reconnects with exponential backoff.

    Example:
    let config = @redis.ClientConfig(host="127.0.0.1", port=6379, password="secret")

    let client = @redis.Client(config~)

    Command

    pub struct Command[T] {
    // private fields
    }
    fn Command::Command(args : Array[Bytes], res_decode_fn : (RawValue) -> T raise) -> Command[T]

    Custom Redis command with a typed result.

    Use Command with Client::execute for commands that do not yet have a typed helper. Pass command parts in Redis order, starting with the command name, and provide a decoder for the response.

    Example:
    let info = client.execute(
    @redis.Command([b"INFO", b"server"], value => value.as_string()),
    )

    Message

    pub struct Message {
    channel : String
    payload : &
    Data

    }

    Message delivered by Client::subscribe.

    Example:
    msg.channel
    msg.payload.text()

    Multi

    pub struct Multi {
    // private fields
    }
    fn Multi::Multi() -> Multi

    Builder for commands that should run inside one Redis transaction.

    Add commands to a Multi, keep the returned tokens, then pass the Multi to Transaction::exec and read each result with MultiResult::get.

    Example:
    let multi = @redis.Multi()

    let old_value = multi.get("account:1")

    let wrote = multi.set("account:1", "updated")

    Multi::append

    fn Multi::append(self : Multi, key : String, value : String) -> MultiToken[Int]

    Multi::decr

    fn Multi::decr(self : Multi, key : String) -> MultiToken[Int]

    Multi::decrby

    fn Multi::decrby(self : Multi, key : String, decrement : Int) -> MultiToken[Int]

    Multi::del

    fn Multi::del(self : Multi, keys : ArrayView[String]) -> MultiToken[Int]

    Multi::echo

    fn Multi::echo(self : Multi, message : String) -> MultiToken[String]

    Multi::exists

    fn Multi::exists(self : Multi, keys : ArrayView[String]) -> MultiToken[Int]

    Multi::expire

    fn Multi::expire(self : Multi, key : String, seconds : Int) -> MultiToken[Bool]

    Multi::get

    fn Multi::get(self : Multi, key : String) -> MultiToken[String?]

    Multi::getrange

    fn Multi::getrange(self : Multi, key : String, start : Int, end : Int) -> MultiToken[String]

    Multi::hdel

    fn Multi::hdel(self : Multi, key : String, fields : ArrayView[String]) -> MultiToken[Int]

    Multi::hexists

    fn Multi::hexists(self : Multi, key : String, field : String) -> MultiToken[Bool]

    Multi::hget

    fn Multi::hget(self : Multi, key : String, field : String) -> MultiToken[String?]

    Multi::hgetall

    fn Multi::hgetall(self : Multi, key : String) -> MultiToken[Map[String, String]]

    Multi::hincrby

    fn Multi::hincrby(self : Multi, key : String, field : String, increment : Int) -> MultiToken[Int]

    Multi::hincrbyfloat

    fn Multi::hincrbyfloat(self : Multi, key : String, field : String, increment : Double) -> MultiToken[Double]

    Multi::hkeys

    fn Multi::hkeys(self : Multi, key : String) -> MultiToken[Array[String]]

    Multi::hlen

    fn Multi::hlen(self : Multi, key : String) -> MultiToken[Int]

    Multi::hmget

    fn Multi::hmget(self : Multi, key : String, fields : ArrayView[String]) -> MultiToken[Array[String?]]

    Multi::hmset

    fn Multi::hmset(self : Multi, key : String, fields : ArrayView[(String, String)]) -> MultiToken[Unit]

    Multi::hscan

    fn Multi::hscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Map[String, String])]

    Multi::hset

    fn Multi::hset(self : Multi, key : String, field : String, value : String) -> MultiToken[Int]

    Multi::hstrlen

    fn Multi::hstrlen(self : Multi, key : String, field : String) -> MultiToken[Int]

    Multi::hvals

    fn Multi::hvals(self : Multi, key : String) -> MultiToken[Array[String]]

    Multi::incr

    fn Multi::incr(self : Multi, key : String) -> MultiToken[Int]

    Multi::incrby

    fn Multi::incrby(self : Multi, key : String, increment : Int) -> MultiToken[Int]

    Multi::incrbyfloat

    fn Multi::incrbyfloat(self : Multi, key : String, increment : Double) -> MultiToken[Double]

    Multi::keys

    fn Multi::keys(self : Multi, pattern : String) -> MultiToken[Array[String]]

    Multi::lindex

    fn Multi::lindex(self : Multi, key : String, index : Int) -> MultiToken[String?]

    Multi::linsert_after

    fn Multi::linsert_after(self : Multi, key : String, pivot : String, value : String) -> MultiToken[Int]

    Multi::linsert_before

    fn Multi::linsert_before(self : Multi, key : String, pivot : String, value : String) -> MultiToken[Int]

    Multi::llen

    fn Multi::llen(self : Multi, key : String) -> MultiToken[Int]

    Multi::lpop

    fn Multi::lpop(self : Multi, key : String) -> MultiToken[String?]

    Multi::lpop_count

    fn Multi::lpop_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

    Multi::lpush

    fn Multi::lpush(self : Multi, key : String, values : ArrayView[String]) -> MultiToken[Int]

    Multi::lrange

    fn Multi::lrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

    Multi::lrem

    fn Multi::lrem(self : Multi, key : String, count : Int, value : String) -> MultiToken[Int]

    Multi::lset

    fn Multi::lset(self : Multi, key : String, index : Int, value : String) -> MultiToken[Unit]

    Multi::ltrim

    fn Multi::ltrim(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Unit]

    Multi::mget

    fn Multi::mget(self : Multi, keys : ArrayView[String]) -> MultiToken[Array[String?]]

    Multi::mset

    fn Multi::mset(self : Multi, items : ArrayView[(String, String)]) -> MultiToken[Unit]

    Multi::msetnx

    fn Multi::msetnx(self : Multi, items : ArrayView[(String, String)]) -> MultiToken[Bool]

    Multi::persist

    fn Multi::persist(self : Multi, key : String) -> MultiToken[Bool]

    Multi::pexpire

    fn Multi::pexpire(self : Multi, key : String, milliseconds : Int) -> MultiToken[Bool]

    Multi::ping

    fn Multi::ping(self : Multi, message? : String) -> MultiToken[String]

    Multi::psetex

    fn Multi::psetex(self : Multi, key : String, milliseconds : Int, value : String) -> MultiToken[Unit]

    Multi::pttl

    fn Multi::pttl(self : Multi, key : String) -> MultiToken[Int]

    Multi::randomkey

    fn Multi::randomkey(self : Multi) -> MultiToken[String?]

    Multi::raw_command

    fn[T] Multi::raw_command(self : Multi, args : ArrayView[BytesView], decode : (RawValue) -> T raise) -> MultiToken[T]

    Adds a custom command to this transaction builder.

    Example:
    let multi = @redis.Multi()

    let size = multi.raw_command([b"DBSIZE"], value => value.as_int())

    Multi::rename

    fn Multi::rename(self : Multi, key : String, new_key : String) -> MultiToken[Unit]

    Multi::renamenx

    fn Multi::renamenx(self : Multi, key : String, new_key : String) -> MultiToken[Bool]

    Multi::rpop

    fn Multi::rpop(self : Multi, key : String) -> MultiToken[String?]

    Multi::rpop_count

    fn Multi::rpop_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

    Multi::rpush

    fn Multi::rpush(self : Multi, key : String, values : ArrayView[String]) -> MultiToken[Int]

    Multi::sadd

    fn Multi::sadd(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

    Multi::scan

    fn Multi::scan(self : Multi, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Array[String])]

    Multi::scard

    fn Multi::scard(self : Multi, key : String) -> MultiToken[Int]

    Multi::sdiff

    fn Multi::sdiff(self : Multi, keys : ArrayView[String]) -> MultiToken[
    HashSet
    [String]]

    Multi::sdiffstore

    fn Multi::sdiffstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

    Multi::set

    fn Multi::set(self : Multi, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> MultiToken[Bool]

    Multi::set_get

    fn Multi::set_get(self : Multi, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> MultiToken[String?]

    Multi::setex

    fn Multi::setex(self : Multi, key : String, seconds : Int, value : String) -> MultiToken[Unit]

    Multi::setnx

    fn Multi::setnx(self : Multi, key : String, value : String) -> MultiToken[Bool]

    Multi::setrange

    fn Multi::setrange(self : Multi, key : String, offset : Int, value : String) -> MultiToken[Int]

    Multi::sinter

    fn Multi::sinter(self : Multi, keys : ArrayView[String]) -> MultiToken[
    HashSet
    [String]]

    Multi::sinterstore

    fn Multi::sinterstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

    Multi::sismember

    fn Multi::sismember(self : Multi, key : String, value : String) -> MultiToken[Bool]

    Multi::smembers

    fn Multi::smembers(self : Multi, key : String) -> MultiToken[
    HashSet
    [String]]

    Multi::smismember

    fn Multi::smismember(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Array[Bool]]

    Multi::smove

    fn Multi::smove(self : Multi, source : String, destination : String, value : String) -> MultiToken[Bool]

    Multi::spop

    fn Multi::spop(self : Multi, key : String) -> MultiToken[String?]

    Multi::spop_count

    fn Multi::spop_count(self : Multi, key : String, count : Int) -> MultiToken[
    HashSet
    [String]]

    Multi::srandmember

    fn Multi::srandmember(self : Multi, key : String) -> MultiToken[String?]

    Multi::srandmember_count

    fn Multi::srandmember_count(self : Multi, key : String, count : Int) -> MultiToken[Array[String]]

    Multi::srem

    fn Multi::srem(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

    Multi::sscan

    fn Multi::sscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String,
    HashSet
    [String])]

    Multi::strlen

    fn Multi::strlen(self : Multi, key : String) -> MultiToken[Int]

    Multi::sunion

    fn Multi::sunion(self : Multi, keys : ArrayView[String]) -> MultiToken[
    HashSet
    [String]]

    Multi::sunionstore

    fn Multi::sunionstore(self : Multi, destination : String, keys : ArrayView[String]) -> MultiToken[Int]

    Multi::ttl

    fn Multi::ttl(self : Multi, key : String) -> MultiToken[Int]

    Multi::type_

    fn Multi::type_(self : Multi, key : String) -> MultiToken[String]

    Multi::zadd

    fn Multi::zadd(self : Multi, key : String, items : ArrayView[(String, Double)]) -> MultiToken[Int]

    Multi::zcard

    fn Multi::zcard(self : Multi, key : String) -> MultiToken[Int]

    Multi::zcount

    fn Multi::zcount(self : Multi, key : String, min : Double, max : Double) -> MultiToken[Int]

    Multi::zincrby

    fn Multi::zincrby(self : Multi, key : String, increment : Double, value : String) -> MultiToken[Double]

    Multi::zpopmax

    fn Multi::zpopmax(self : Multi, key : String, count? : Int) -> MultiToken[Array[(String, Double)]]

    Multi::zpopmin

    fn Multi::zpopmin(self : Multi, key : String, count? : Int) -> MultiToken[Array[(String, Double)]]

    Multi::zrange

    fn Multi::zrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

    Multi::zrange_with_scores

    fn Multi::zrange_with_scores(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[(String, Double)]]

    Multi::zrangebyscore

    fn Multi::zrangebyscore(self : Multi, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> MultiToken[Array[String]] raise

    Multi::zrangebyscore_with_scores

    fn Multi::zrangebyscore_with_scores(self : Multi, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> MultiToken[Array[(String, Double)]] raise

    Multi::zrank

    fn Multi::zrank(self : Multi, key : String, value : String) -> MultiToken[Int?]

    Multi::zrem

    fn Multi::zrem(self : Multi, key : String, members : ArrayView[String]) -> MultiToken[Int]

    Multi::zremrangebyrank

    fn Multi::zremrangebyrank(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Int]

    Multi::zremrangebyscore

    fn Multi::zremrangebyscore(self : Multi, key : String, min : Double, max : Double) -> MultiToken[Int]

    Multi::zrevrange

    fn Multi::zrevrange(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[String]]

    Multi::zrevrange_with_scores

    fn Multi::zrevrange_with_scores(self : Multi, key : String, start : Int, stop : Int) -> MultiToken[Array[(String, Double)]]

    Multi::zrevrank

    fn Multi::zrevrank(self : Multi, key : String, value : String) -> MultiToken[Int?]

    Multi::zscan

    fn Multi::zscan(self : Multi, key : String, cursor : String, pattern? : String, count? : Int) -> MultiToken[(String, Array[(String, Double)])]

    Multi::zscore

    fn Multi::zscore(self : Multi, key : String, value : String) -> MultiToken[Double?]

    MultiResult

    type MultiResult

    Result set returned by a successful Transaction::exec.

    MultiResult::get

    fn[T] MultiResult::get(self : MultiResult, token : MultiToken[T]) -> T raise

    Reads the result for a queued command.

    Raises if Redis returned an error for that command or if the response cannot be decoded as the token's expected type.

    Example:
    let value = result.get(old_value)

    MultiToken

    type MultiToken[T]

    Result handle for one command added to Multi.

    Use the token with MultiResult::get after Transaction::exec succeeds.

    PatternMessage

    pub struct PatternMessage {
    pattern : String
    channel : String
    payload : &
    Data

    }

    Message delivered by Client::psubscribe.

    Example:
    msg.pattern
    msg.channel
    msg.payload.text()

    RawValue

    type RawValue

    Raw Redis response passed to custom command decoders.

    Use the as_* helpers to turn a raw response into the type your custom command should return.

    Example:
    @redis.Command([b"DBSIZE"], value => value.as_int())

    RawValue::as_array

    fn[T] RawValue::as_array(self : RawValue, convert : (RawValue) -> T raise) -> Array[T] raise

    Reads the response as an array by decoding each item with convert.

    RawValue::as_bool

    fn RawValue::as_bool(self : RawValue) -> Bool raise

    Reads the response as Bool.

    This accepts Redis boolean replies and integer replies where 0 means false and 1 means true.

    RawValue::as_bytes

    fn RawValue::as_bytes(self : RawValue) -> Bytes raise

    Reads the response as raw bytes.

    Example:
    @redis.Command([b"GET", b"blob"], value => value.as_bytes())

    RawValue::as_double

    fn RawValue::as_double(self : RawValue) -> Double raise

    Reads the response as Double.

    RawValue::as_int

    fn RawValue::as_int(self : RawValue) -> Int raise

    Reads the response as Int.

    Example:
    @redis.Command([b"DBSIZE"], value => value.as_int())

    RawValue::as_int64

    fn RawValue::as_int64(self : RawValue) -> Int64 raise

    Reads the response as Int64.

    RawValue::as_option

    fn[T] RawValue::as_option(self : RawValue, convert : (RawValue) -> T raise) -> T? raise

    Reads Redis null as None; otherwise decodes the value with convert.

    Example:
    @redis.Command([b"GET", b"name"], value => {
    value.as_option(item => item.as_string())
    })

    RawValue::as_set

    fn[T : Hash + Eq] RawValue::as_set(self : RawValue, convert : (RawValue) -> T raise) ->
    HashSet
    [T] raise

    Reads the response as a HashSet by decoding each item with convert.

    RawValue::as_string

    fn RawValue::as_string(self : RawValue) -> String raise

    Reads the response as a UTF-8 string.

    Example:
    @redis.Command([b"PING"], value => value.as_string())

    RawValue::as_string_map

    fn RawValue::as_string_map(self : RawValue) -> Map[String, String] raise

    Reads the response as a string map.

    Example:
    @redis.Command([b"HGETALL", b"user:1"], value => value.as_string_map())

    RawValue::expect_ok

    fn RawValue::expect_ok(self : RawValue) -> Unit raise

    Succeeds only when the response is OK.

    RawValue::is_null

    fn RawValue::is_null(self : RawValue) -> Bool

    Returns whether the response is Redis null.

    Example:
    @redis.Command([b"GET", b"missing"], value => value.is_null())

    Transaction

    type Transaction

    Transaction context passed to Client::transaction.

    Use it only inside the callback passed to Client::transaction.

    Transaction::append

    async fn Transaction::append(self : Transaction, key : String, value : String) -> Int

    Transaction::decr

    async fn Transaction::decr(self : Transaction, key : String) -> Int

    Transaction::decrby

    async fn Transaction::decrby(self : Transaction, key : String, decrement : Int) -> Int

    Transaction::del

    async fn Transaction::del(self : Transaction, keys : ArrayView[String]) -> Int

    Transaction::echo

    async fn Transaction::echo(self : Transaction, message : String) -> String

    Transaction::exec

    async fn Transaction::exec(self : Transaction, multi : Multi) -> MultiResult?

    Executes commands added to multi with Redis MULTI/EXEC.

    Returns None when watched keys changed before EXEC. Returns Some(result) on success; read individual command results with MultiResult::get.

    Transaction::exists

    async fn Transaction::exists(self : Transaction, keys : ArrayView[String]) -> Int

    Transaction::expire

    async fn Transaction::expire(self : Transaction, key : String, seconds : Int) -> Bool

    Transaction::get

    async fn Transaction::get(self : Transaction, key : String) -> String?

    Transaction::getrange

    async fn Transaction::getrange(self : Transaction, key : String, start : Int, end : Int) -> String

    Transaction::hdel

    async fn Transaction::hdel(self : Transaction, key : String, fields : ArrayView[String]) -> Int

    Transaction::hexists

    async fn Transaction::hexists(self : Transaction, key : String, field : String) -> Bool

    Transaction::hget

    async fn Transaction::hget(self : Transaction, key : String, field : String) -> String?

    Transaction::hgetall

    async fn Transaction::hgetall(self : Transaction, key : String) -> Map[String, String]

    Transaction::hincrby

    async fn Transaction::hincrby(self : Transaction, key : String, field : String, increment : Int) -> Int

    Transaction::hincrbyfloat

    async fn Transaction::hincrbyfloat(self : Transaction, key : String, field : String, increment : Double) -> Double

    Transaction::hkeys

    async fn Transaction::hkeys(self : Transaction, key : String) -> Array[String]

    Transaction::hlen

    async fn Transaction::hlen(self : Transaction, key : String) -> Int

    Transaction::hmget

    async fn Transaction::hmget(self : Transaction, key : String, fields : ArrayView[String]) -> Array[String?]

    Transaction::hmset

    async fn Transaction::hmset(self : Transaction, key : String, fields : ArrayView[(String, String)]) -> Unit

    Transaction::hscan

    async fn Transaction::hscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Map[String, String])

    Transaction::hset

    async fn Transaction::hset(self : Transaction, key : String, field : String, value : String) -> Int

    Transaction::hstrlen

    async fn Transaction::hstrlen(self : Transaction, key : String, field : String) -> Int

    Transaction::hvals

    async fn Transaction::hvals(self : Transaction, key : String) -> Array[String]

    Transaction::incr

    async fn Transaction::incr(self : Transaction, key : String) -> Int

    Transaction::incrby

    async fn Transaction::incrby(self : Transaction, key : String, increment : Int) -> Int

    Transaction::incrbyfloat

    async fn Transaction::incrbyfloat(self : Transaction, key : String, increment : Double) -> Double

    Transaction::keys

    async fn Transaction::keys(self : Transaction, pattern : String) -> Array[String]

    Transaction::lindex

    async fn Transaction::lindex(self : Transaction, key : String, index : Int) -> String?

    Transaction::linsert_after

    async fn Transaction::linsert_after(self : Transaction, key : String, pivot : String, value : String) -> Int

    Transaction::linsert_before

    async fn Transaction::linsert_before(self : Transaction, key : String, pivot : String, value : String) -> Int

    Transaction::llen

    async fn Transaction::llen(self : Transaction, key : String) -> Int

    Transaction::lpop

    async fn Transaction::lpop(self : Transaction, key : String) -> String?

    Transaction::lpop_count

    async fn Transaction::lpop_count(self : Transaction, key : String, count : Int) -> Array[String]

    Transaction::lpush

    async fn Transaction::lpush(self : Transaction, key : String, values : ArrayView[String]) -> Int

    Transaction::lrange

    async fn Transaction::lrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

    Transaction::lrem

    async fn Transaction::lrem(self : Transaction, key : String, count : Int, value : String) -> Int

    Transaction::lset

    async fn Transaction::lset(self : Transaction, key : String, index : Int, value : String) -> Unit

    Transaction::ltrim

    async fn Transaction::ltrim(self : Transaction, key : String, start : Int, stop : Int) -> Unit

    Transaction::mget

    async fn Transaction::mget(self : Transaction, keys : ArrayView[String]) -> Array[String?]

    Transaction::mset

    async fn Transaction::mset(self : Transaction, items : ArrayView[(String, String)]) -> Unit

    Transaction::msetnx

    async fn Transaction::msetnx(self : Transaction, items : ArrayView[(String, String)]) -> Bool

    Transaction::persist

    async fn Transaction::persist(self : Transaction, key : String) -> Bool

    Transaction::pexpire

    async fn Transaction::pexpire(self : Transaction, key : String, milliseconds : Int) -> Bool

    Transaction::ping

    async fn Transaction::ping(self : Transaction, message? : String) -> String

    Transaction::psetex

    async fn Transaction::psetex(self : Transaction, key : String, milliseconds : Int, value : String) -> Unit

    Transaction::pttl

    async fn Transaction::pttl(self : Transaction, key : String) -> Int

    Transaction::randomkey

    async fn Transaction::randomkey(self : Transaction) -> String?

    Transaction::raw_command

    async fn Transaction::raw_command(self : Transaction, args : ArrayView[BytesView]) -> RawValue

    Runs one custom command immediately on the transaction connection.

    This is useful for commands not covered by typed transaction helpers.

    Transaction::rename

    async fn Transaction::rename(self : Transaction, key : String, new_key : String) -> Unit

    Transaction::renamenx

    async fn Transaction::renamenx(self : Transaction, key : String, new_key : String) -> Bool

    Transaction::rpop

    async fn Transaction::rpop(self : Transaction, key : String) -> String?

    Transaction::rpop_count

    async fn Transaction::rpop_count(self : Transaction, key : String, count : Int) -> Array[String]

    Transaction::rpush

    async fn Transaction::rpush(self : Transaction, key : String, values : ArrayView[String]) -> Int

    Transaction::sadd

    async fn Transaction::sadd(self : Transaction, key : String, members : ArrayView[String]) -> Int

    Transaction::scan

    async fn Transaction::scan(self : Transaction, cursor : String, pattern? : String, count? : Int) -> (String, Array[String])

    Transaction::scard

    async fn Transaction::scard(self : Transaction, key : String) -> Int

    Transaction::sdiff

    async fn Transaction::sdiff(self : Transaction, keys : ArrayView[String]) ->
    HashSet
    [String]

    Transaction::sdiffstore

    async fn Transaction::sdiffstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

    Transaction::set

    async fn Transaction::set(self : Transaction, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> Bool

    Transaction::set_get

    async fn Transaction::set_get(self : Transaction, key : String, value : String, ex? : Int, px? : Int, nx? : Bool, xx? : Bool) -> String?

    Transaction::setex

    async fn Transaction::setex(self : Transaction, key : String, seconds : Int, value : String) -> Unit

    Transaction::setnx

    async fn Transaction::setnx(self : Transaction, key : String, value : String) -> Bool

    Transaction::setrange

    async fn Transaction::setrange(self : Transaction, key : String, offset : Int, value : String) -> Int

    Transaction::sinter

    async fn Transaction::sinter(self : Transaction, keys : ArrayView[String]) ->
    HashSet
    [String]

    Transaction::sinterstore

    async fn Transaction::sinterstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

    Transaction::sismember

    async fn Transaction::sismember(self : Transaction, key : String, value : String) -> Bool

    Transaction::smembers

    async fn Transaction::smembers(self : Transaction, key : String) ->
    HashSet
    [String]

    Transaction::smismember

    async fn Transaction::smismember(self : Transaction, key : String, members : ArrayView[String]) -> Array[Bool]

    Transaction::smove

    async fn Transaction::smove(self : Transaction, source : String, destination : String, value : String) -> Bool

    Transaction::spop

    async fn Transaction::spop(self : Transaction, key : String) -> String?

    Transaction::spop_count

    async fn Transaction::spop_count(self : Transaction, key : String, count : Int) ->
    HashSet
    [String]

    Transaction::srandmember

    async fn Transaction::srandmember(self : Transaction, key : String) -> String?

    Transaction::srandmember_count

    async fn Transaction::srandmember_count(self : Transaction, key : String, count : Int) -> Array[String]

    Transaction::srem

    async fn Transaction::srem(self : Transaction, key : String, members : ArrayView[String]) -> Int

    Transaction::sscan

    async fn Transaction::sscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String,
    HashSet
    [String])

    Transaction::strlen

    async fn Transaction::strlen(self : Transaction, key : String) -> Int

    Transaction::sunion

    async fn Transaction::sunion(self : Transaction, keys : ArrayView[String]) ->
    HashSet
    [String]

    Transaction::sunionstore

    async fn Transaction::sunionstore(self : Transaction, destination : String, keys : ArrayView[String]) -> Int

    Transaction::ttl

    async fn Transaction::ttl(self : Transaction, key : String) -> Int

    Transaction::type_

    async fn Transaction::type_(self : Transaction, key : String) -> String

    Transaction::watch

    async fn Transaction::watch(self : Transaction, keys : ArrayView[String]) -> Unit

    Watches keys for optimistic locking.

    If any watched key changes before exec, Transaction::exec returns None.

    Transaction::zadd

    async fn Transaction::zadd(self : Transaction, key : String, items : ArrayView[(String, Double)]) -> Int

    Transaction::zcard

    async fn Transaction::zcard(self : Transaction, key : String) -> Int

    Transaction::zcount

    async fn Transaction::zcount(self : Transaction, key : String, min : Double, max : Double) -> Int

    Transaction::zincrby

    async fn Transaction::zincrby(self : Transaction, key : String, increment : Double, value : String) -> Double

    Transaction::zpopmax

    async fn Transaction::zpopmax(self : Transaction, key : String, count? : Int) -> Array[(String, Double)]

    Transaction::zpopmin

    async fn Transaction::zpopmin(self : Transaction, key : String, count? : Int) -> Array[(String, Double)]

    Transaction::zrange

    async fn Transaction::zrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

    Transaction::zrange_with_scores

    async fn Transaction::zrange_with_scores(self : Transaction, key : String, start : Int, stop : Int) -> Array[(String, Double)]

    Transaction::zrangebyscore

    async fn Transaction::zrangebyscore(self : Transaction, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[String]

    Transaction::zrangebyscore_with_scores

    async fn Transaction::zrangebyscore_with_scores(self : Transaction, key : String, min : Double, max : Double, offset? : Int, count? : Int) -> Array[(String, Double)]

    Transaction::zrank

    async fn Transaction::zrank(self : Transaction, key : String, value : String) -> Int?

    Transaction::zrem

    async fn Transaction::zrem(self : Transaction, key : String, members : ArrayView[String]) -> Int

    Transaction::zremrangebyrank

    async fn Transaction::zremrangebyrank(self : Transaction, key : String, start : Int, stop : Int) -> Int

    Transaction::zremrangebyscore

    async fn Transaction::zremrangebyscore(self : Transaction, key : String, min : Double, max : Double) -> Int

    Transaction::zrevrange

    async fn Transaction::zrevrange(self : Transaction, key : String, start : Int, stop : Int) -> Array[String]

    Transaction::zrevrange_with_scores

    async fn Transaction::zrevrange_with_scores(self : Transaction, key : String, start : Int, stop : Int) -> Array[(String, Double)]

    Transaction::zrevrank

    async fn Transaction::zrevrank(self : Transaction, key : String, value : String) -> Int?

    Transaction::zscan

    async fn Transaction::zscan(self : Transaction, key : String, cursor : String, pattern? : String, count? : Int) -> (String, Array[(String, Double)])

    Transaction::zscore

    async fn Transaction::zscore(self : Transaction, key : String, value : String) -> Double?