From f5cadeb8cbf86b9258affd9c94aaac00e45da67a Mon Sep 17 00:00:00 2001 From: Isaac Harris-Holt Date: Fri, 15 Aug 2025 17:41:51 +0100 Subject: [PATCH 1/2] handle lpop and rpop with a count higher than 1 --- src/valkyrie.gleam | 31 +++++-------------------------- test/valkyrie_test.gleam | 31 +++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/valkyrie.gleam b/src/valkyrie.gleam index 04aeee9..484dc8f 100644 --- a/src/valkyrie.gleam +++ b/src/valkyrie.gleam @@ -711,6 +711,7 @@ fn expect_bulk_string_array( ) } }) + [resp.Null] -> Error(NotFound) _ -> Error(RespError(resp.error_string(expected: "array", got: value))) } } @@ -1593,21 +1594,10 @@ pub fn lpop( key: String, count: Int, timeout: Int, -) -> Result(String, Error) { +) -> Result(List(String), Error) { ["LPOP", key, int.to_string(count)] |> execute(conn, _, timeout) - |> result.try(fn(value) { - case value { - // When count is provided, Redis returns an array - [resp.Array([resp.BulkString(str)])] -> Ok(str) - [resp.Array([])] -> Error(NotFound) - [resp.Null] -> Error(NotFound) - _ -> - Error( - RespError(resp.error_string(expected: "string or array", got: value)), - ) - } - }) + |> result.try(expect_bulk_string_array) } /// Remove and return elements from the right (tail) of a list. @@ -1620,21 +1610,10 @@ pub fn rpop( key: String, count: Int, timeout: Int, -) -> Result(String, Error) { +) -> Result(List(String), Error) { ["RPOP", key, int.to_string(count)] |> execute(conn, _, timeout) - |> result.try(fn(value) { - case value { - // When count is provided, Redis returns an array - [resp.Array([resp.BulkString(str)])] -> Ok(str) - [resp.Array([])] -> Error(NotFound) - [resp.Null] -> Error(NotFound) - _ -> - Error( - RespError(resp.error_string(expected: "string or array", got: value)), - ) - } - }) + |> result.try(expect_bulk_string_array) } /// Get an element from a list by its index. diff --git a/test/valkyrie_test.gleam b/test/valkyrie_test.gleam index c14f5cc..daffae7 100644 --- a/test/valkyrie_test.gleam +++ b/test/valkyrie_test.gleam @@ -822,11 +822,38 @@ pub fn lpop_rpop_test() { let assert Ok(_) = valkyrie.rpush(conn, "test:pop", ["a", "b", "c"], 1000) - let assert Ok("a") = valkyrie.lpop(conn, "test:pop", 1, 1000) - let assert Ok("c") = valkyrie.rpop(conn, "test:pop", 1, 1000) + let assert Ok(["a"]) = valkyrie.lpop(conn, "test:pop", 1, 1000) + let assert Ok(["c"]) = valkyrie.rpop(conn, "test:pop", 1, 1000) let assert Ok(1) = valkyrie.llen(conn, "test:pop", 1000) } +pub fn lpop_rpop_multiple_test() { + use conn <- get_test_conn() + + let assert Ok(_) = + valkyrie.rpush(conn, "test:pop_multiple", ["a", "b", "c", "d", "e"], 1000) + + // Pop multiple from left + let assert Ok(["a", "b"]) = valkyrie.lpop(conn, "test:pop_multiple", 2, 1000) + let assert Ok(3) = valkyrie.llen(conn, "test:pop_multiple", 1000) + + // Pop multiple from right + let assert Ok(["e", "d"]) = valkyrie.rpop(conn, "test:pop_multiple", 2, 1000) + let assert Ok(1) = valkyrie.llen(conn, "test:pop_multiple", 1000) + + let assert Ok(["c"]) = valkyrie.lpop(conn, "test:pop_multiple", 3, 1000) + let assert Ok(0) = valkyrie.llen(conn, "test:pop_multiple", 1000) + + let assert Error(valkyrie.NotFound) = + valkyrie.lpop(conn, "test:pop_multiple", 1, 1000) + let assert Error(valkyrie.NotFound) = + valkyrie.lpop(conn, "test:pop_multiple", 2, 1000) + let assert Error(valkyrie.NotFound) = + valkyrie.rpop(conn, "test:pop_multiple", 1, 1000) + let assert Error(valkyrie.NotFound) = + valkyrie.rpop(conn, "test:pop_multiple", 2, 1000) +} + pub fn lindex_test() { use conn <- get_test_conn() From 7125c3079c7dae4e1f93cf6ce08912b352d95c6d Mon Sep 17 00:00:00 2001 From: Isaac Harris-Holt Date: Fri, 15 Aug 2025 17:52:17 +0100 Subject: [PATCH 2/2] update gleam.toml and changelog --- CHANGELOG.md | 5 +++++ gleam.toml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7e5af9..bdd0137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 4.0.0 - 2025-08-15 + +- Update `lpop` and `rpop` to return string arrays. Previously they would error if a + count higher than 1 was provided. + ## 3.0.0 - 2025-06-29 - Update `mug` and add support for IPv6 connections. diff --git a/gleam.toml b/gleam.toml index cc5bd3a..2bf8aee 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "valkyrie" -version = "3.0.0" +version = "4.0.0" description = "A Gleam client for Valkey, KeyDB, Redis, Dragonfly and other Redis-compatible databases." gleam = ">= 1.11.0"