From 83f43c37bba822f6d99b7e7f6c9054864a1faad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragutin=20Marjanovi=C4=87?= Date: Wed, 12 Apr 2023 21:53:58 +0200 Subject: [PATCH] Unify 'Value' and 'Unknown' command arguments (#815) --- .../src/main/scala/zio/redis/Input.scala | 594 +++++++++--------- .../main/scala/zio/redis/api/Strings.scala | 2 +- .../redis/internal/RespCommandArgument.scala | 10 +- .../src/test/scala/zio/redis/InputSpec.scala | 302 ++++----- 4 files changed, 448 insertions(+), 460 deletions(-) diff --git a/modules/redis/src/main/scala/zio/redis/Input.scala b/modules/redis/src/main/scala/zio/redis/Input.scala index 3a09bbe..861df16 100644 --- a/modules/redis/src/main/scala/zio/redis/Input.scala +++ b/modules/redis/src/main/scala/zio/redis/Input.scala @@ -17,7 +17,7 @@ package zio.redis import zio._ -import zio.redis.internal.{RespCommand, RespCommandArgument, Utf8Codec} +import zio.redis.internal.{RespCommand, RespCommandArgument} import zio.schema.codec.BinaryCodec import java.time.Instant @@ -42,7 +42,7 @@ object Input { case object AddressInput extends Input[Address] { def encode(data: Address): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + RespCommand(RespCommandArgument.Value(data.asString)) } case object AggregateInput extends Input[Aggregate] { @@ -55,38 +55,23 @@ object Input { RespCommand(RespCommandArgument.Literal(data.asString)) } - case object AuthInput extends Input[Auth] { - import Utf8Codec.codec + final case class ArbitraryKeyInput[A: BinaryCodec]() extends Input[A] { + def encode(data: A): RespCommand = + RespCommand(RespCommandArgument.Key(data)) + } + final case class ArbitraryValueInput[A: BinaryCodec]() extends Input[A] { + def encode(data: A): RespCommand = + RespCommand(RespCommandArgument.Value(data)) + } + + case object AuthInput extends Input[Auth] { def encode(data: Auth): RespCommand = data.username match { case Some(username) => RespCommand(RespCommandArgument.Value(username), RespCommandArgument.Value(data.password)) case None => RespCommand(RespCommandArgument.Value(data.password)) } - - } - - case object BoolInput extends Input[Boolean] { - def encode(data: Boolean): RespCommand = - RespCommand(RespCommandArgument.Literal(if (data) "1" else "0")) - } - - case object StralgoLcsQueryTypeInput extends Input[StrAlgoLcsQueryType] { - def encode(data: StrAlgoLcsQueryType): RespCommand = data match { - case StrAlgoLcsQueryType.Len => RespCommand(RespCommandArgument.Literal("LEN")) - case StrAlgoLcsQueryType.Idx(minMatchLength, withMatchLength) => { - val idx = Chunk.single(RespCommandArgument.Literal("IDX")) - val min = - if (minMatchLength > 1) - Chunk(RespCommandArgument.Literal("MINMATCHLEN"), RespCommandArgument.Unknown(minMatchLength.toString)) - else Chunk.empty[RespCommandArgument] - val length = - if (withMatchLength) Chunk.single(RespCommandArgument.Literal("WITHMATCHLEN")) - else Chunk.empty[RespCommandArgument] - RespCommand(Chunk(idx, min, length).flatten) - } - } } case object BitFieldCommandInput extends Input[BitFieldCommand] { @@ -97,22 +82,22 @@ object Input { case BitFieldGet(t, o) => Chunk( RespCommandArgument.Literal("GET"), - RespCommandArgument.Unknown(t.asString), - RespCommandArgument.Unknown(o.toString) + RespCommandArgument.Value(t.asString), + RespCommandArgument.Value(o.toString) ) case BitFieldSet(t, o, v) => Chunk( RespCommandArgument.Literal("SET"), - RespCommandArgument.Unknown(t.asString), - RespCommandArgument.Unknown(o.toString), - RespCommandArgument.Unknown(v.toString) + RespCommandArgument.Value(t.asString), + RespCommandArgument.Value(o.toString), + RespCommandArgument.Value(v.toString) ) case BitFieldIncr(t, o, i) => Chunk( RespCommandArgument.Literal("INCRBY"), - RespCommandArgument.Unknown(t.asString), - RespCommandArgument.Unknown(o.toString), - RespCommandArgument.Unknown(i.toString) + RespCommandArgument.Value(t.asString), + RespCommandArgument.Value(o.toString), + RespCommandArgument.Value(i.toString) ) case bfo: BitFieldOverflow => Chunk(RespCommandArgument.Literal("OVERFLOW"), RespCommandArgument.Literal(bfo.asString)) @@ -128,15 +113,25 @@ object Input { case object BitPosRangeInput extends Input[BitPosRange] { def encode(data: BitPosRange): RespCommand = { - val start = RespCommandArgument.Unknown(data.start.toString) - val respArgs = data.end.fold(Chunk.single(start))(end => Chunk(start, RespCommandArgument.Unknown(end.toString))) + val start = RespCommandArgument.Value(data.start.toString) + val respArgs = data.end.fold(Chunk.single(start))(end => Chunk(start, RespCommandArgument.Value(end.toString))) RespCommand(respArgs) } } + case object BlockInput extends Input[Duration] { + def encode(data: Duration): RespCommand = + RespCommand(RespCommandArgument.Literal("BLOCK"), RespCommandArgument.Value(data.toMillis.toString)) + } + + case object BoolInput extends Input[Boolean] { + def encode(data: Boolean): RespCommand = + RespCommand(RespCommandArgument.Literal(if (data) "1" else "0")) + } + case object ByInput extends Input[String] { def encode(data: String): RespCommand = - RespCommand(RespCommandArgument.Literal("BY"), RespCommandArgument.Unknown(data)) + RespCommand(RespCommandArgument.Literal("BY"), RespCommandArgument.Value(data)) } case object ChangedInput extends Input[Changed] { @@ -147,25 +142,20 @@ object Input { case object ClientKillInput extends Input[ClientKillFilter] { def encode(data: ClientKillFilter): RespCommand = data match { case addr: ClientKillFilter.Address => - RespCommand(RespCommandArgument.Literal("ADDR"), RespCommandArgument.Unknown(addr.asString)) + RespCommand(RespCommandArgument.Literal("ADDR"), RespCommandArgument.Value(addr.asString)) case laddr: ClientKillFilter.LocalAddress => - RespCommand(RespCommandArgument.Literal("LADDR"), RespCommandArgument.Unknown(laddr.asString)) + RespCommand(RespCommandArgument.Literal("LADDR"), RespCommandArgument.Value(laddr.asString)) case ClientKillFilter.Id(clientId) => - RespCommand(RespCommandArgument.Literal("ID"), RespCommandArgument.Unknown(clientId.toString)) + RespCommand(RespCommandArgument.Literal("ID"), RespCommandArgument.Value(clientId.toString)) case ClientKillFilter.Type(clientType) => RespCommand(RespCommandArgument.Literal("TYPE"), RespCommandArgument.Literal(clientType.asString)) case ClientKillFilter.User(username) => - RespCommand(RespCommandArgument.Literal("USER"), RespCommandArgument.Unknown(username)) + RespCommand(RespCommandArgument.Literal("USER"), RespCommandArgument.Value(username)) case ClientKillFilter.SkipMe(skip) => RespCommand(RespCommandArgument.Literal("SKIPME"), RespCommandArgument.Literal(if (skip) "YES" else "NO")) } } - case object ClientTypeInput extends Input[ClientType] { - def encode(data: ClientType): RespCommand = - RespCommand(RespCommandArgument.Literal("TYPE"), RespCommandArgument.Literal(data.asString)) - } - case object ClientPauseModeInput extends Input[ClientPauseMode] { def encode(data: ClientPauseMode): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) @@ -187,11 +177,11 @@ object Input { val loopChunk = if (noLoop) RespCommand(RespCommandArgument.Literal("NOLOOP")) else RespCommand.empty RespCommand(RespCommandArgument.Literal("ON")) ++ clientRedir.fold(RespCommand.empty)(id => - RespCommand(RespCommandArgument.Literal("REDIRECT"), RespCommandArgument.Unknown(id.toString)) + RespCommand(RespCommandArgument.Literal("REDIRECT"), RespCommandArgument.Value(id.toString)) ) ++ RespCommand( prefixes.flatMap(prefix => - Chunk(RespCommandArgument.Literal("PREFIX"), RespCommandArgument.Unknown(prefix)) + Chunk(RespCommandArgument.Literal("PREFIX"), RespCommandArgument.Value(prefix)) ) ) ++ modeChunk ++ @@ -201,68 +191,106 @@ object Input { } } - case object CopyInput extends Input[Copy] { - def encode(data: Copy): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) - } - - case object CountInput extends Input[Count] { - def encode(data: Count): RespCommand = - RespCommand(RespCommandArgument.Literal("COUNT"), RespCommandArgument.Unknown(data.count.toString)) - } - - case object RedisTypeInput extends Input[RedisType] { - def encode(data: RedisType): RespCommand = + case object ClientTypeInput extends Input[ClientType] { + def encode(data: ClientType): RespCommand = RespCommand(RespCommandArgument.Literal("TYPE"), RespCommandArgument.Literal(data.asString)) } - case object PatternInput extends Input[Pattern] { - def encode(data: Pattern): RespCommand = - RespCommand(RespCommandArgument.Literal("MATCH"), RespCommandArgument.Unknown(data.pattern)) - } - - case object GetInput extends Input[String] { + case object CommandNameInput extends Input[String] { def encode(data: String): RespCommand = - RespCommand(RespCommandArgument.Literal("GET"), RespCommandArgument.Unknown(data)) + RespCommand(RespCommandArgument.CommandName(data)) } - case object PositionInput extends Input[Position] { - def encode(data: Position): RespCommand = + case object CopyInput extends Input[Copy] { + def encode(data: Copy): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) } - case object SideInput extends Input[Side] { - def encode(data: Side): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + case object CountInput extends Input[Count] { + def encode(data: Count): RespCommand = + RespCommand(RespCommandArgument.Literal("COUNT"), RespCommandArgument.Value(data.count.toString)) } case object DoubleInput extends Input[Double] { def encode(data: Double): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.toString)) + RespCommand(RespCommandArgument.Value(data.toString)) } case object DurationMillisecondsInput extends Input[Duration] { def encode(data: Duration): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.toMillis.toString)) + RespCommand(RespCommandArgument.Value(data.toMillis.toString)) } case object DurationSecondsInput extends Input[Duration] { def encode(data: Duration): RespCommand = { val seconds = TimeUnit.MILLISECONDS.toSeconds(data.toMillis) - RespCommand(RespCommandArgument.Unknown(seconds.toString)) + RespCommand(RespCommandArgument.Value(seconds.toString)) } } case object DurationTtlInput extends Input[Duration] { def encode(data: Duration): RespCommand = { val milliseconds = data.toMillis - RespCommand(RespCommandArgument.Literal("PX"), RespCommandArgument.Unknown(milliseconds.toString)) + RespCommand(RespCommandArgument.Literal("PX"), RespCommandArgument.Value(milliseconds.toString)) + } + } + + final case class EvalInput[-K, -V](inputK: Input[K], inputV: Input[V]) extends Input[(String, Chunk[K], Chunk[V])] { + def encode(data: (String, Chunk[K], Chunk[V])): RespCommand = { + val (lua, keys, args) = data + val encodedScript = RespCommand(RespCommandArgument.Value(lua), RespCommandArgument.Value(keys.size.toString)) + val encodedKeys = keys.foldLeft(RespCommand.empty)((acc, a) => + acc ++ inputK.encode(a).mapArguments(arg => RespCommandArgument.Key(arg.value.value)) + ) + val encodedArgs = args.foldLeft(RespCommand.empty)((acc, a) => + acc ++ inputV.encode(a).mapArguments(arg => RespCommandArgument.Value(arg.value.value)) + ) + encodedScript ++ encodedKeys ++ encodedArgs } } case object FreqInput extends Input[Freq] { def encode(data: Freq): RespCommand = - RespCommand(RespCommandArgument.Literal("FREQ"), RespCommandArgument.Unknown(data.frequency)) + RespCommand(RespCommandArgument.Literal("FREQ"), RespCommandArgument.Value(data.frequency)) + } + + case object GetInput extends Input[String] { + def encode(data: String): RespCommand = + RespCommand(RespCommandArgument.Literal("GET"), RespCommandArgument.Value(data)) + } + + final case class GetExInput[K: BinaryCodec]() extends Input[(K, Expire, Duration)] { + def encode(data: (K, Expire, Duration)): RespCommand = + data match { + case (key, Expire.SetExpireSeconds, duration) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode( + duration + ) + case (key, Expire.SetExpireMilliseconds, duration) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput + .encode(duration) + } + } + + final case class GetExAtInput[K: BinaryCodec]() extends Input[(K, ExpiredAt, Instant)] { + def encode(data: (K, ExpiredAt, Instant)): RespCommand = + data match { + case (key, ExpiredAt.SetExpireAtSeconds, instant) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode( + instant + ) + case (key, ExpiredAt.SetExpireAtMilliseconds, instant) => + RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput + .encode(instant) + } + } + + final case class GetExPersistInput[K: BinaryCodec]() extends Input[(K, Boolean)] { + def encode(data: (K, Boolean)): RespCommand = + RespCommand( + if (data._2) Chunk(RespCommandArgument.Key(data._1), RespCommandArgument.Literal("PERSIST")) + else Chunk(RespCommandArgument.Key(data._1)) + ) } case object GetKeywordInput extends Input[GetKeyword] { @@ -270,9 +298,28 @@ object Input { RespCommand(RespCommandArgument.Literal(data.asString)) } + case object IdleInput extends Input[Duration] { + def encode(data: Duration): RespCommand = + RespCommand(RespCommandArgument.Literal("IDLE"), RespCommandArgument.Value(data.toMillis.toString)) + } + case object IdleTimeInput extends Input[IdleTime] { def encode(data: IdleTime): RespCommand = - RespCommand(RespCommandArgument.Literal("IDLETIME"), RespCommandArgument.Unknown(data.seconds.toString)) + RespCommand(RespCommandArgument.Literal("IDLETIME"), RespCommandArgument.Value(data.seconds.toString)) + } + + case object IdInput extends Input[Long] { + def encode(data: Long): RespCommand = + RespCommand(RespCommandArgument.Literal("ID"), RespCommandArgument.Value(data.toString)) + } + + case object IdsInput extends Input[(Long, List[Long])] { + def encode(data: (Long, List[Long])): RespCommand = + RespCommand( + Chunk.fromIterable( + RespCommandArgument.Literal("ID") +: (data._1 :: data._2).map(id => RespCommandArgument.Value(id.toString)) + ) + ) } case object IncrementInput extends Input[Increment] { @@ -289,27 +336,37 @@ object Input { def encode(data: Limit): RespCommand = RespCommand( RespCommandArgument.Literal("LIMIT"), - RespCommandArgument.Unknown(data.offset.toString), - RespCommandArgument.Unknown(data.count.toString) + RespCommandArgument.Value(data.offset.toString), + RespCommandArgument.Value(data.count.toString) ) } + case object ListMaxLenInput extends Input[ListMaxLen] { + def encode(data: ListMaxLen): RespCommand = + RespCommand(RespCommandArgument.Literal("MAXLEN"), RespCommandArgument.Value(data.count.toString)) + } + case object LongInput extends Input[Long] { def encode(data: Long): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.toString)) + RespCommand(RespCommandArgument.Value(data.toString)) } case object LongLatInput extends Input[LongLat] { def encode(data: LongLat): RespCommand = RespCommand( - RespCommandArgument.Unknown(data.longitude.toString), - RespCommandArgument.Unknown(data.latitude.toString) + RespCommandArgument.Value(data.longitude.toString), + RespCommandArgument.Value(data.latitude.toString) ) } final case class MemberScoreInput[M: BinaryCodec]() extends Input[MemberScore[M]] { def encode(data: MemberScore[M]): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.score.toString), RespCommandArgument.Value(data.member)) + RespCommand(RespCommandArgument.Value(data.score.toString), RespCommandArgument.Value(data.member)) + } + + case object NoAckInput extends Input[NoAck] { + def encode(data: NoAck): RespCommand = + RespCommand(RespCommandArgument.Value(data.asString)) } case object NoInput extends Input[Unit] { @@ -321,159 +378,105 @@ object Input { (data._1 :: data._2).foldLeft(RespCommand.empty)((acc, a) => acc ++ input.encode(a)) } - case object OrderInput extends Input[Order] { - def encode(data: Order): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + final case class OptionalInput[-A](a: Input[A]) extends Input[Option[A]] { + def encode(data: Option[A]): RespCommand = + data.fold(RespCommand.empty)(a.encode) } - case object RadiusUnitInput extends Input[RadiusUnit] { - def encode(data: RadiusUnit): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + case object OrderInput extends Input[Order] { + def encode(data: Order): RespCommand = + RespCommand(RespCommandArgument.Value(data.asString)) } - case object RangeInput extends Input[Range] { - def encode(data: Range): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.start.toString), RespCommandArgument.Unknown(data.end.toString)) + case object PatternInput extends Input[Pattern] { + def encode(data: Pattern): RespCommand = + RespCommand(RespCommandArgument.Literal("MATCH"), RespCommandArgument.Value(data.pattern)) } - case object ReplaceInput extends Input[Replace] { - def encode(data: Replace): RespCommand = + case object PositionInput extends Input[Position] { + def encode(data: Position): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) } - case object StoreDistInput extends Input[StoreDist] { - def encode(data: StoreDist): RespCommand = - RespCommand(RespCommandArgument.Literal("STOREDIST"), RespCommandArgument.Unknown(data.key)) - } - - case object StoreInput extends Input[Store] { - def encode(data: Store): RespCommand = - RespCommand(RespCommandArgument.Literal("STORE"), RespCommandArgument.Unknown(data.key)) - } - - case object StringInput extends Input[String] { - def encode(data: String): RespCommand = - RespCommand(RespCommandArgument.Unknown(data)) - } - - case object CommandNameInput extends Input[String] { - def encode(data: String): RespCommand = - RespCommand(RespCommandArgument.CommandName(data)) + case object RadiusUnitInput extends Input[RadiusUnit] { + def encode(data: RadiusUnit): RespCommand = + RespCommand(RespCommandArgument.Value(data.asString)) } - final case class ArbitraryValueInput[A: BinaryCodec]() extends Input[A] { - def encode(data: A): RespCommand = - RespCommand(RespCommandArgument.Value(data)) + case object RangeInput extends Input[Range] { + def encode(data: Range): RespCommand = + RespCommand(RespCommandArgument.Value(data.start.toString), RespCommandArgument.Value(data.end.toString)) } - final case class ArbitraryKeyInput[A: BinaryCodec]() extends Input[A] { - def encode(data: A): RespCommand = - RespCommand(RespCommandArgument.Key(data)) + case object RankInput extends Input[Rank] { + def encode(data: Rank): RespCommand = + RespCommand(RespCommandArgument.Literal("RANK"), RespCommandArgument.Value(data.rank.toString)) } - case object ValueInput extends Input[Chunk[Byte]] { - def encode(data: Chunk[Byte]): RespCommand = - RespCommand(RespCommandArgument.Value(data)) + case object RedisTypeInput extends Input[RedisType] { + def encode(data: RedisType): RespCommand = + RespCommand(RespCommandArgument.Literal("TYPE"), RespCommandArgument.Literal(data.asString)) } - final case class OptionalInput[-A](a: Input[A]) extends Input[Option[A]] { - def encode(data: Option[A]): RespCommand = - data.fold(RespCommand.empty)(a.encode) + case object ReplaceInput extends Input[Replace] { + def encode(data: Replace): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - case object TimeSecondsInput extends Input[Instant] { - def encode(data: Instant): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.getEpochSecond.toString)) + case object RetryCountInput extends Input[Long] { + def encode(data: Long): RespCommand = + RespCommand(RespCommandArgument.Literal("RETRYCOUNT"), RespCommandArgument.Value(data.toString)) } - case object TimeMillisecondsInput extends Input[Instant] { - def encode(data: Instant): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.toEpochMilli.toString)) + case object ScriptDebugInput extends Input[DebugMode] { + def encode(data: DebugMode): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - case object WeightsInput extends Input[::[Double]] { - def encode(data: ::[Double]): RespCommand = { - val args = data.foldLeft(Chunk.single[RespCommandArgument](RespCommandArgument.Literal("WEIGHTS"))) { (acc, a) => - acc ++ Chunk.single(RespCommandArgument.Unknown(a.toString)) - } - RespCommand(args) - } + case object ScriptFlushInput extends Input[FlushMode] { + def encode(data: FlushMode): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - case object IdleInput extends Input[Duration] { - def encode(data: Duration): RespCommand = - RespCommand(RespCommandArgument.Literal("IDLE"), RespCommandArgument.Unknown(data.toMillis.toString)) + case object SideInput extends Input[Side] { + def encode(data: Side): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - case object TimeInput extends Input[Duration] { - def encode(data: Duration): RespCommand = - RespCommand(RespCommandArgument.Literal("TIME"), RespCommandArgument.Unknown(data.toMillis.toString)) + case object StoreDistInput extends Input[StoreDist] { + def encode(data: StoreDist): RespCommand = + RespCommand(RespCommandArgument.Literal("STOREDIST"), RespCommandArgument.Value(data.key)) } - case object RetryCountInput extends Input[Long] { - def encode(data: Long): RespCommand = - RespCommand(RespCommandArgument.Literal("RETRYCOUNT"), RespCommandArgument.Unknown(data.toString)) + case object StoreInput extends Input[Store] { + def encode(data: Store): RespCommand = + RespCommand(RespCommandArgument.Literal("STORE"), RespCommandArgument.Value(data.key)) } - final case class XGroupCreateInput[K: BinaryCodec, G: BinaryCodec, I: BinaryCodec]() - extends Input[XGroupCommand.Create[K, G, I]] { - def encode(data: XGroupCommand.Create[K, G, I]): RespCommand = { - val chunk = Chunk( - RespCommandArgument.Literal("CREATE"), - RespCommandArgument.Key(data.key), - RespCommandArgument.Unknown(data.group), - RespCommandArgument.Unknown(data.id) - ) - - RespCommand(if (data.mkStream) chunk :+ RespCommandArgument.Literal(MkStream.asString) else chunk) + case object StrAlgoLcsQueryTypeInput extends Input[StrAlgoLcsQueryType] { + def encode(data: StrAlgoLcsQueryType): RespCommand = data match { + case StrAlgoLcsQueryType.Len => RespCommand(RespCommandArgument.Literal("LEN")) + case StrAlgoLcsQueryType.Idx(minMatchLength, withMatchLength) => + val idx = Chunk.single(RespCommandArgument.Literal("IDX")) + val min = + if (minMatchLength > 1) + Chunk(RespCommandArgument.Literal("MINMATCHLEN"), RespCommandArgument.Value(minMatchLength.toString)) + else Chunk.empty[RespCommandArgument] + val length = + if (withMatchLength) Chunk.single(RespCommandArgument.Literal("WITHMATCHLEN")) + else Chunk.empty[RespCommandArgument] + RespCommand(Chunk(idx, min, length).flatten) } } - final case class XGroupSetIdInput[K: BinaryCodec, G: BinaryCodec, I: BinaryCodec]() - extends Input[XGroupCommand.SetId[K, G, I]] { - def encode(data: XGroupCommand.SetId[K, G, I]): RespCommand = - RespCommand( - RespCommandArgument.Literal("SETID"), - RespCommandArgument.Key(data.key), - RespCommandArgument.Unknown(data.group), - RespCommandArgument.Unknown(data.id) - ) - } - - final case class XGroupDestroyInput[K: BinaryCodec, G: BinaryCodec]() extends Input[XGroupCommand.Destroy[K, G]] { - def encode(data: XGroupCommand.Destroy[K, G]): RespCommand = - RespCommand( - RespCommandArgument.Literal("DESTROY"), - RespCommandArgument.Key(data.key), - RespCommandArgument.Unknown(data.group) - ) - } - - final case class XGroupCreateConsumerInput[K: BinaryCodec, G: BinaryCodec, C: BinaryCodec]() - extends Input[XGroupCommand.CreateConsumer[K, G, C]] { - def encode(data: XGroupCommand.CreateConsumer[K, G, C]): RespCommand = - RespCommand( - RespCommandArgument.Literal("CREATECONSUMER"), - RespCommandArgument.Key(data.key), - RespCommandArgument.Unknown(data.group), - RespCommandArgument.Unknown(data.consumer) - ) - } - - final case class XGroupDelConsumerInput[K: BinaryCodec, G: BinaryCodec, C: BinaryCodec]() - extends Input[XGroupCommand.DelConsumer[K, G, C]] { - def encode(data: XGroupCommand.DelConsumer[K, G, C]): RespCommand = - RespCommand( - RespCommandArgument.Literal("DELCONSUMER"), - RespCommandArgument.Key(data.key), - RespCommandArgument.Unknown(data.group), - RespCommandArgument.Unknown(data.consumer) - ) - } + case object StreamMaxLenInput extends Input[StreamMaxLen] { + def encode(data: StreamMaxLen): RespCommand = { + val chunk = + if (data.approximate) Chunk(RespCommandArgument.Literal("MAXLEN"), RespCommandArgument.Literal("~")) + else Chunk.single(RespCommandArgument.Literal("MAXLEN")) - case object BlockInput extends Input[Duration] { - def encode(data: Duration): RespCommand = - RespCommand(RespCommandArgument.Literal("BLOCK"), RespCommandArgument.Unknown(data.toMillis.toString)) + RespCommand(chunk :+ RespCommandArgument.Value(data.count.toString)) + } } final case class StreamsInput[K: BinaryCodec, V: BinaryCodec]() extends Input[((K, V), Chunk[(K, V)])] { @@ -486,29 +489,24 @@ object Input { } } - case object NoAckInput extends Input[NoAck] { - def encode(data: NoAck): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + case object StringInput extends Input[String] { + def encode(data: String): RespCommand = + RespCommand(RespCommandArgument.Value(data)) } - case object StreamMaxLenInput extends Input[StreamMaxLen] { - def encode(data: StreamMaxLen): RespCommand = { - val chunk = - if (data.approximate) Chunk(RespCommandArgument.Literal("MAXLEN"), RespCommandArgument.Literal("~")) - else Chunk.single(RespCommandArgument.Literal("MAXLEN")) - - RespCommand(chunk :+ RespCommandArgument.Unknown(data.count.toString)) - } + case object TimeInput extends Input[Duration] { + def encode(data: Duration): RespCommand = + RespCommand(RespCommandArgument.Literal("TIME"), RespCommandArgument.Value(data.toMillis.toString)) } - case object ListMaxLenInput extends Input[ListMaxLen] { - def encode(data: ListMaxLen): RespCommand = - RespCommand(RespCommandArgument.Literal("MAXLEN"), RespCommandArgument.Unknown(data.count.toString)) + case object TimeMillisecondsInput extends Input[Instant] { + def encode(data: Instant): RespCommand = + RespCommand(RespCommandArgument.Value(data.toEpochMilli.toString)) } - case object RankInput extends Input[Rank] { - def encode(data: Rank): RespCommand = - RespCommand(RespCommandArgument.Literal("RANK"), RespCommandArgument.Unknown(data.rank.toString)) + case object TimeSecondsInput extends Input[Instant] { + def encode(data: Instant): RespCommand = + RespCommand(RespCommandArgument.Value(data.getEpochSecond.toString)) } final case class Tuple2[-A, -B](_1: Input[A], _2: Input[B]) extends Input[(A, B)] { @@ -613,90 +611,57 @@ object Input { _9.encode(data._9) ++ _10.encode(data._10) ++ _11.encode(data._11) } + case object UnblockBehaviorInput extends Input[UnblockBehavior] { + def encode(data: UnblockBehavior): RespCommand = + RespCommand(RespCommandArgument.Value(data.asString)) + } + case object UpdateInput extends Input[Update] { def encode(data: Update): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + RespCommand(RespCommandArgument.Value(data.asString)) } - final case class GetExPersistInput[K: BinaryCodec]() extends Input[(K, Boolean)] { - def encode(data: (K, Boolean)): RespCommand = - RespCommand( - if (data._2) Chunk(RespCommandArgument.Key(data._1), RespCommandArgument.Literal("PERSIST")) - else Chunk(RespCommandArgument.Key(data._1)) - ) + case object ValueInput extends Input[Chunk[Byte]] { + def encode(data: Chunk[Byte]): RespCommand = + RespCommand(RespCommandArgument.Value(data)) } - final case class GetExInput[K: BinaryCodec]() extends Input[(K, Expire, Duration)] { - def encode(data: (K, Expire, Duration)): RespCommand = - data match { - case (key, Expire.SetExpireSeconds, duration) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EX")) ++ DurationSecondsInput.encode( - duration - ) - case (key, Expire.SetExpireMilliseconds, duration) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PX")) ++ DurationMillisecondsInput - .encode(duration) - } + final case class Varargs[-A](input: Input[A]) extends Input[Iterable[A]] { + def encode(data: Iterable[A]): RespCommand = + data.foldLeft(RespCommand.empty)((acc, a) => acc ++ input.encode(a)) } - final case class GetExAtInput[K: BinaryCodec]() extends Input[(K, ExpiredAt, Instant)] { - def encode(data: (K, ExpiredAt, Instant)): RespCommand = - data match { - case (key, ExpiredAt.SetExpireAtSeconds, instant) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("EXAT")) ++ TimeSecondsInput.encode( - instant - ) - case (key, ExpiredAt.SetExpireAtMilliseconds, instant) => - RespCommand(RespCommandArgument.Key(key), RespCommandArgument.Literal("PXAT")) ++ TimeMillisecondsInput - .encode(instant) + case object WeightsInput extends Input[::[Double]] { + def encode(data: ::[Double]): RespCommand = { + val args = data.foldLeft(Chunk.single[RespCommandArgument](RespCommandArgument.Literal("WEIGHTS"))) { (acc, a) => + acc ++ Chunk.single(RespCommandArgument.Value(a.toString)) } + RespCommand(args) + } } - case object IdInput extends Input[Long] { - def encode(data: Long): RespCommand = - RespCommand(RespCommandArgument.Literal("ID"), RespCommandArgument.Unknown(data.toString)) - } - - case object IdsInput extends Input[(Long, List[Long])] { - def encode(data: (Long, List[Long])): RespCommand = - RespCommand( - Chunk.fromIterable( - RespCommandArgument.Literal("ID") +: (data._1 :: data._2).map(id => RespCommandArgument.Unknown(id.toString)) - ) - ) - } - - case object UnblockBehaviorInput extends Input[UnblockBehavior] { - def encode(data: UnblockBehavior): RespCommand = - RespCommand(RespCommandArgument.Unknown(data.asString)) + case object WithCoordInput extends Input[WithCoord] { + def encode(data: WithCoord): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - final case class Varargs[-A](input: Input[A]) extends Input[Iterable[A]] { - def encode(data: Iterable[A]): RespCommand = - data.foldLeft(RespCommand.empty)((acc, a) => acc ++ input.encode(a)) + case object WithDistInput extends Input[WithDist] { + def encode(data: WithDist): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - final case class EvalInput[-K, -V](inputK: Input[K], inputV: Input[V]) extends Input[(String, Chunk[K], Chunk[V])] { - def encode(data: (String, Chunk[K], Chunk[V])): RespCommand = { - val (lua, keys, args) = data - val encodedScript = RespCommand(RespCommandArgument.Unknown(lua), RespCommandArgument.Unknown(keys.size.toString)) - val encodedKeys = keys.foldLeft(RespCommand.empty)((acc, a) => - acc ++ inputK.encode(a).mapArguments(arg => RespCommandArgument.Key(arg.value.value)) - ) - val encodedArgs = args.foldLeft(RespCommand.empty)((acc, a) => - acc ++ inputV.encode(a).mapArguments(arg => RespCommandArgument.Value(arg.value.value)) - ) - encodedScript ++ encodedKeys ++ encodedArgs - } + case object WithForceInput extends Input[WithForce] { + def encode(data: WithForce): RespCommand = + RespCommand(RespCommandArgument.Literal(data.asString)) } - case object ScriptDebugInput extends Input[DebugMode] { - def encode(data: DebugMode): RespCommand = + case object WithHashInput extends Input[WithHash] { + def encode(data: WithHash): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) } - case object ScriptFlushInput extends Input[FlushMode] { - def encode(data: FlushMode): RespCommand = + case object WithJustIdInput extends Input[WithJustId] { + def encode(data: WithJustId): RespCommand = RespCommand(RespCommandArgument.Literal(data.asString)) } @@ -705,29 +670,60 @@ object Input { RespCommand(RespCommandArgument.Literal(data.asString)) } - case object WithCoordInput extends Input[WithCoord] { - def encode(data: WithCoord): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + final case class XGroupCreateConsumerInput[K: BinaryCodec, G: BinaryCodec, C: BinaryCodec]() + extends Input[XGroupCommand.CreateConsumer[K, G, C]] { + def encode(data: XGroupCommand.CreateConsumer[K, G, C]): RespCommand = + RespCommand( + RespCommandArgument.Literal("CREATECONSUMER"), + RespCommandArgument.Key(data.key), + RespCommandArgument.Value(data.group), + RespCommandArgument.Value(data.consumer) + ) } - case object WithDistInput extends Input[WithDist] { - def encode(data: WithDist): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + final case class XGroupCreateInput[K: BinaryCodec, G: BinaryCodec, I: BinaryCodec]() + extends Input[XGroupCommand.Create[K, G, I]] { + def encode(data: XGroupCommand.Create[K, G, I]): RespCommand = { + val chunk = Chunk( + RespCommandArgument.Literal("CREATE"), + RespCommandArgument.Key(data.key), + RespCommandArgument.Value(data.group), + RespCommandArgument.Value(data.id) + ) + + RespCommand(if (data.mkStream) chunk :+ RespCommandArgument.Literal(MkStream.asString) else chunk) + } } - case object WithHashInput extends Input[WithHash] { - def encode(data: WithHash): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + final case class XGroupDelConsumerInput[K: BinaryCodec, G: BinaryCodec, C: BinaryCodec]() + extends Input[XGroupCommand.DelConsumer[K, G, C]] { + def encode(data: XGroupCommand.DelConsumer[K, G, C]): RespCommand = + RespCommand( + RespCommandArgument.Literal("DELCONSUMER"), + RespCommandArgument.Key(data.key), + RespCommandArgument.Value(data.group), + RespCommandArgument.Value(data.consumer) + ) } - case object WithForceInput extends Input[WithForce] { - def encode(data: WithForce): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + final case class XGroupDestroyInput[K: BinaryCodec, G: BinaryCodec]() extends Input[XGroupCommand.Destroy[K, G]] { + def encode(data: XGroupCommand.Destroy[K, G]): RespCommand = + RespCommand( + RespCommandArgument.Literal("DESTROY"), + RespCommandArgument.Key(data.key), + RespCommandArgument.Value(data.group) + ) } - case object WithJustIdInput extends Input[WithJustId] { - def encode(data: WithJustId): RespCommand = - RespCommand(RespCommandArgument.Literal(data.asString)) + final case class XGroupSetIdInput[K: BinaryCodec, G: BinaryCodec, I: BinaryCodec]() + extends Input[XGroupCommand.SetId[K, G, I]] { + def encode(data: XGroupCommand.SetId[K, G, I]): RespCommand = + RespCommand( + RespCommandArgument.Literal("SETID"), + RespCommandArgument.Key(data.key), + RespCommandArgument.Value(data.group), + RespCommandArgument.Value(data.id) + ) } case object YesNoInput extends Input[Boolean] { diff --git a/modules/redis/src/main/scala/zio/redis/api/Strings.scala b/modules/redis/src/main/scala/zio/redis/api/Strings.scala index 09914b3..dbe1e40 100644 --- a/modules/redis/src/main/scala/zio/redis/api/Strings.scala +++ b/modules/redis/src/main/scala/zio/redis/api/Strings.scala @@ -635,7 +635,7 @@ trait Strings extends RedisEnvironment { ArbitraryValueInput[String](), ArbitraryKeyInput[K](), ArbitraryKeyInput[K](), - OptionalInput(StralgoLcsQueryTypeInput) + OptionalInput(StrAlgoLcsQueryTypeInput) ), StrAlgoLcsOutput, executor diff --git a/modules/redis/src/main/scala/zio/redis/internal/RespCommandArgument.scala b/modules/redis/src/main/scala/zio/redis/internal/RespCommandArgument.scala index e6cdb2a..0bf226a 100644 --- a/modules/redis/src/main/scala/zio/redis/internal/RespCommandArgument.scala +++ b/modules/redis/src/main/scala/zio/redis/internal/RespCommandArgument.scala @@ -27,15 +27,6 @@ private[redis] sealed trait RespCommandArgument { private[redis] object RespCommandArgument { - final case class Unknown(bytes: Chunk[Byte]) extends RespCommandArgument { - lazy val value: RespValue.BulkString = RespValue.BulkString(bytes) - } - - object Unknown { - def apply(str: String): Unknown = Unknown(Chunk.fromArray(str.getBytes(StandardCharsets.UTF_8))) - def apply[A](data: A)(implicit codec: BinaryCodec[A]): Unknown = Unknown(codec.encode(data)) - } - final case class CommandName(str: String) extends RespCommandArgument { lazy val value: RespValue.BulkString = RespValue.bulkString(str) } @@ -64,5 +55,6 @@ private[redis] object RespCommandArgument { object Value { def apply[A](data: A)(implicit codec: BinaryCodec[A]): Value = Value(codec.encode(data)) + def apply(str: String): Value = Value(Chunk.fromArray(str.getBytes(StandardCharsets.UTF_8))) } } diff --git a/modules/redis/src/test/scala/zio/redis/InputSpec.scala b/modules/redis/src/test/scala/zio/redis/InputSpec.scala index fb805cf..f819b47 100644 --- a/modules/redis/src/test/scala/zio/redis/InputSpec.scala +++ b/modules/redis/src/test/scala/zio/redis/InputSpec.scala @@ -33,7 +33,7 @@ object InputSpec extends BaseSpec { ip <- ZIO.succeed(InetAddress.getByName("127.0.0.1")) port <- ZIO.succeed(42) result <- ZIO.attempt(AddressInput.encode(Address(ip, port))) - } yield assert(result)(equalTo(RespCommand(Unknown("127.0.0.1:42")))) + } yield assert(result)(equalTo(RespCommand(Value("127.0.0.1:42")))) } ), suite("Aggregate")( @@ -91,28 +91,28 @@ object InputSpec extends BaseSpec { ), suite("Stralgocommand")( test("length option") { - assert(StralgoLcsQueryTypeInput.encode(StrAlgoLcsQueryType.Len))( + assert(StrAlgoLcsQueryTypeInput.encode(StrAlgoLcsQueryType.Len))( equalTo(RespCommand(Literal("LEN"))) ) }, test("idx option default") { - assert(StralgoLcsQueryTypeInput.encode(Idx()))( + assert(StrAlgoLcsQueryTypeInput.encode(Idx()))( equalTo(RespCommand(Literal("IDX"))) ) }, test("idx option with minmatchlength") { - assert(StralgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2)))( - equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Unknown("2"))) + assert(StrAlgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2)))( + equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Value("2"))) ) }, test("idx option with withmatchlength") { - assert(StralgoLcsQueryTypeInput.encode(Idx(withMatchLength = true)))( + assert(StrAlgoLcsQueryTypeInput.encode(Idx(withMatchLength = true)))( equalTo(RespCommand(Literal("IDX"), Literal("WITHMATCHLEN"))) ) }, test("idx option with minmatchlength and withmatchlength") { - assert(StralgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2, withMatchLength = true)))( - equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Unknown("2"), Literal("WITHMATCHLEN"))) + assert(StrAlgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2, withMatchLength = true)))( + equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Value("2"), Literal("WITHMATCHLEN"))) ) } ), @@ -120,47 +120,47 @@ object InputSpec extends BaseSpec { test("get with unsigned type and positive offset") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldGet(UnsignedInt(3), 2))) - } yield assert(result)(equalTo(RespCommand(Literal("GET"), Unknown("u3"), Unknown("2")))) + } yield assert(result)(equalTo(RespCommand(Literal("GET"), Value("u3"), Value("2")))) }, test("get with signed type and negative offset") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldGet(SignedInt(3), -2))) - } yield assert(result)(equalTo(RespCommand(Literal("GET"), Unknown("i3"), Unknown("-2")))) + } yield assert(result)(equalTo(RespCommand(Literal("GET"), Value("i3"), Value("-2")))) }, test("get with unsigned type and zero offset") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldGet(UnsignedInt(3), 0))) - } yield assert(result)(equalTo(RespCommand(Literal("GET"), Unknown("u3"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("GET"), Value("u3"), Value("0")))) }, test("set with unsigned type, positive offset and positive value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldSet(UnsignedInt(3), 2, 100L))) - } yield assert(result)(equalTo(RespCommand(Literal("SET"), Unknown("u3"), Unknown("2"), Unknown("100")))) + } yield assert(result)(equalTo(RespCommand(Literal("SET"), Value("u3"), Value("2"), Value("100")))) }, test("set with signed type, negative offset and negative value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldSet(SignedInt(3), -2, -100L))) - } yield assert(result)(equalTo(RespCommand(Literal("SET"), Unknown("i3"), Unknown("-2"), Unknown("-100")))) + } yield assert(result)(equalTo(RespCommand(Literal("SET"), Value("i3"), Value("-2"), Value("-100")))) }, test("set with unsigned type, zero offset and zero value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldSet(UnsignedInt(3), 0, 0L))) - } yield assert(result)(equalTo(RespCommand(Literal("SET"), Unknown("u3"), Unknown("0"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("SET"), Value("u3"), Value("0"), Value("0")))) }, test("incr with unsigned type, positive offset and positive value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldIncr(UnsignedInt(3), 2, 100L))) - } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Unknown("u3"), Unknown("2"), Unknown("100")))) + } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Value("u3"), Value("2"), Value("100")))) }, test("incr with signed type, negative offset and negative value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldIncr(SignedInt(3), -2, -100L))) - } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Unknown("i3"), Unknown("-2"), Unknown("-100")))) + } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Value("i3"), Value("-2"), Value("-100")))) }, test("incr with unsigned type, zero offset and zero value") { for { result <- ZIO.attempt(BitFieldCommandInput.encode(BitFieldIncr(UnsignedInt(3), 0, 0L))) - } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Unknown("u3"), Unknown("0"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("INCRBY"), Value("u3"), Value("0"), Value("0")))) }, test("overflow sat") { for { @@ -204,19 +204,19 @@ object InputSpec extends BaseSpec { test("with only start") { for { result <- ZIO.attempt(BitPosRangeInput.encode(BitPosRange(1.second.toMillis, None))) - } yield assert(result)(equalTo(RespCommand(Unknown("1000")))) + } yield assert(result)(equalTo(RespCommand(Value("1000")))) }, test("with start and the end") { for { result <- ZIO.attempt(BitPosRangeInput.encode(BitPosRange(0.second.toMillis, Some(1.second.toMillis)))) - } yield assert(result)(equalTo(RespCommand(Unknown("0"), Unknown("1000")))) + } yield assert(result)(equalTo(RespCommand(Value("0"), Value("1000")))) } ), suite("By")( test("with a pattern") { for { result <- ZIO.attempt(ByInput.encode("mykey_*")) - } yield assert(result)(equalTo(RespCommand(Literal("BY"), Unknown("mykey_*")))) + } yield assert(result)(equalTo(RespCommand(Literal("BY"), Value("mykey_*")))) } ), suite("Changed")( @@ -232,20 +232,20 @@ object InputSpec extends BaseSpec { address <- ZIO.succeed(InetAddress.getByName("127.0.0.1")) port <- ZIO.succeed(42) result <- ZIO.attempt(ClientKillInput.encode(ClientKillFilter.Address(address, port))) - } yield assert(result)(equalTo(RespCommand(Literal("ADDR"), Unknown("127.0.0.1:42")))) + } yield assert(result)(equalTo(RespCommand(Literal("ADDR"), Value("127.0.0.1:42")))) }, test("local address") { for { address <- ZIO.succeed(InetAddress.getByName("127.0.0.1")) port <- ZIO.succeed(42) result <- ZIO.attempt(ClientKillInput.encode(ClientKillFilter.LocalAddress(address, port))) - } yield assert(result)(equalTo(RespCommand(Literal("LADDR"), Unknown(s"127.0.0.1:42")))) + } yield assert(result)(equalTo(RespCommand(Literal("LADDR"), Value(s"127.0.0.1:42")))) }, test("client id") { for { id <- ZIO.succeed(42L) result <- ZIO.attempt(ClientKillInput.encode(ClientKillFilter.Id(id))) - } yield assert(result)(equalTo(RespCommand(Literal("ID"), Unknown("42")))) + } yield assert(result)(equalTo(RespCommand(Literal("ID"), Value("42")))) }, test("type") { for { @@ -257,7 +257,7 @@ object InputSpec extends BaseSpec { for { user <- ZIO.succeed("Foo Bar") result <- ZIO.attempt(ClientKillInput.encode(ClientKillFilter.User(user))) - } yield assert(result)(equalTo(RespCommand(Literal("USER"), Unknown("Foo Bar")))) + } yield assert(result)(equalTo(RespCommand(Literal("USER"), Value("Foo Bar")))) }, test("skip me") { for { @@ -290,8 +290,8 @@ object InputSpec extends BaseSpec { result <- ZIO.attempt(ClientTrackingInput.encode(Some((Some(clientId), None, true, prefixes)))) } yield assert(result)( equalTo( - RespCommand(Literal("ON"), Literal("REDIRECT"), Unknown(clientId.toString)) ++ prefixes - .map(p => RespCommand(Literal("PREFIX"), Unknown(p))) + RespCommand(Literal("ON"), Literal("REDIRECT"), Value(clientId.toString)) ++ prefixes + .map(p => RespCommand(Literal("PREFIX"), Value(p))) .fold(RespCommand.empty)(_ ++ _) ++ RespCommand(Literal("NOLOOP")) ) ) @@ -316,17 +316,17 @@ object InputSpec extends BaseSpec { test("positive value") { for { result <- ZIO.attempt(CountInput.encode(Count(3L))) - } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Unknown("3")))) + } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Value("3")))) }, test("negative value") { for { result <- ZIO.attempt(CountInput.encode(Count(-3L))) - } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Unknown("-3")))) + } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Value("-3")))) }, test("zero value") { for { result <- ZIO.attempt(CountInput.encode(Count(0L))) - } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("COUNT"), Value("0")))) } ), suite("Position")( @@ -377,77 +377,77 @@ object InputSpec extends BaseSpec { test("positive value") { for { result <- ZIO.attempt(DoubleInput.encode(4.2d)) - } yield assert(result)(equalTo(RespCommand(Unknown("4.2")))) + } yield assert(result)(equalTo(RespCommand(Value("4.2")))) }, test("negative value") { for { result <- ZIO.attempt(DoubleInput.encode(-4.2d)) - } yield assert(result)(equalTo(RespCommand(Unknown("-4.2")))) + } yield assert(result)(equalTo(RespCommand(Value("-4.2")))) }, test("zero value") { for { result <- ZIO.attempt(DoubleInput.encode(0d)) - } yield assert(result)(equalTo(RespCommand(Unknown("0.0")))) + } yield assert(result)(equalTo(RespCommand(Value("0.0")))) } ), suite("DurationMilliseconds")( test("1 second") { for { result <- ZIO.attempt(DurationMillisecondsInput.encode(1.second)) - } yield assert(result)(equalTo(RespCommand(Unknown("1000")))) + } yield assert(result)(equalTo(RespCommand(Value("1000")))) }, test("100 milliseconds") { for { result <- ZIO.attempt(DurationMillisecondsInput.encode(100.millis)) - } yield assert(result)(equalTo(RespCommand(Unknown("100")))) + } yield assert(result)(equalTo(RespCommand(Value("100")))) } ), suite("DurationSeconds")( test("1 minute") { for { result <- ZIO.attempt(DurationSecondsInput.encode(1.minute)) - } yield assert(result)(equalTo(RespCommand(Unknown("60")))) + } yield assert(result)(equalTo(RespCommand(Value("60")))) }, test("1 second") { for { result <- ZIO.attempt(DurationSecondsInput.encode(1.second)) - } yield assert(result)(equalTo(RespCommand(Unknown("1")))) + } yield assert(result)(equalTo(RespCommand(Value("1")))) }, test("100 milliseconds") { for { result <- ZIO.attempt(DurationSecondsInput.encode(100.millis)) - } yield assert(result)(equalTo(RespCommand(Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Value("0")))) } ), suite("DurationTtl")( test("1 second") { for { result <- ZIO.attempt(DurationTtlInput.encode(1.second)) - } yield assert(result)(equalTo(RespCommand(Literal("PX"), Unknown("1000")))) + } yield assert(result)(equalTo(RespCommand(Literal("PX"), Value("1000")))) }, test("100 milliseconds") { for { result <- ZIO.attempt(DurationTtlInput.encode(100.millis)) - } yield assert(result)(equalTo(RespCommand(Literal("PX"), Unknown("100")))) + } yield assert(result)(equalTo(RespCommand(Literal("PX"), Value("100")))) } ), suite("Freq")( test("empty string") { for { result <- ZIO.attempt(FreqInput.encode(Freq(""))) - } yield assert(result)(equalTo(RespCommand(Literal("FREQ"), Unknown("")))) + } yield assert(result)(equalTo(RespCommand(Literal("FREQ"), Value("")))) }, test("non-empty string") { for { result <- ZIO.attempt(FreqInput.encode(Freq("frequency"))) - } yield assert(result)(equalTo(RespCommand(Literal("FREQ"), Unknown("frequency")))) + } yield assert(result)(equalTo(RespCommand(Literal("FREQ"), Value("frequency")))) } ), suite("Get")( test("with a pattern") { for { result <- ZIO.attempt(GetInput.encode("mypattern_*")) - } yield assert(result)(equalTo(RespCommand(Literal("GET"), Unknown("mypattern_*")))) + } yield assert(result)(equalTo(RespCommand(Literal("GET"), Value("mypattern_*")))) } ), suite("GetKeyword")( @@ -461,12 +461,12 @@ object InputSpec extends BaseSpec { test("0 seconds") { for { result <- ZIO.attempt(IdleTimeInput.encode(IdleTime(0))) - } yield assert(result)(equalTo(RespCommand(Literal("IDLETIME"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("IDLETIME"), Value("0")))) }, test("5 seconds") { for { result <- ZIO.attempt(IdleTimeInput.encode(IdleTime(5))) - } yield assert(result)(equalTo(RespCommand(Literal("IDLETIME"), Unknown("5")))) + } yield assert(result)(equalTo(RespCommand(Literal("IDLETIME"), Value("5")))) } ), suite("Increment")( @@ -561,83 +561,83 @@ object InputSpec extends BaseSpec { test("with positive offset and positive count") { for { result <- ZIO.attempt(LimitInput.encode(Limit(4L, 5L))) - } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Unknown("4"), Unknown("5")))) + } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Value("4"), Value("5")))) }, test("with negative offset and negative count") { for { result <- ZIO.attempt(LimitInput.encode(Limit(-4L, -5L))) - } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Unknown("-4"), Unknown("-5")))) + } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Value("-4"), Value("-5")))) }, test("with zero offset and zero count") { for { result <- ZIO.attempt(LimitInput.encode(Limit(0L, 0L))) - } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Unknown("0"), Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Literal("LIMIT"), Value("0"), Value("0")))) } ), suite("Long")( test("positive value") { for { result <- ZIO.attempt(LongInput.encode(4L)) - } yield assert(result)(equalTo(RespCommand(Unknown("4")))) + } yield assert(result)(equalTo(RespCommand(Value("4")))) }, test("negative value") { for { result <- ZIO.attempt(LongInput.encode(-4L)) - } yield assert(result)(equalTo(RespCommand(Unknown("-4")))) + } yield assert(result)(equalTo(RespCommand(Value("-4")))) }, test("zero value") { for { result <- ZIO.attempt(LongInput.encode(0L)) - } yield assert(result)(equalTo(RespCommand(Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Value("0")))) } ), suite("LongLat")( test("positive longitude and latitude") { for { result <- ZIO.attempt(LongLatInput.encode(LongLat(4.2d, 5.2d))) - } yield assert(result)(equalTo(RespCommand(Unknown("4.2"), Unknown("5.2")))) + } yield assert(result)(equalTo(RespCommand(Value("4.2"), Value("5.2")))) }, test("negative longitude and latitude") { for { result <- ZIO.attempt(LongLatInput.encode(LongLat(-4.2d, -5.2d))) - } yield assert(result)(equalTo(RespCommand(Unknown("-4.2"), Unknown("-5.2")))) + } yield assert(result)(equalTo(RespCommand(Value("-4.2"), Value("-5.2")))) }, test("zero longitude and latitude") { for { result <- ZIO.attempt(LongLatInput.encode(LongLat(0d, 0d))) - } yield assert(result)(equalTo(RespCommand(Unknown("0.0"), Unknown("0.0")))) + } yield assert(result)(equalTo(RespCommand(Value("0.0"), Value("0.0")))) } ), suite("MemberScore")( test("with positive score and empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(4.2d, ""))) - } yield assert(result)(equalTo(RespCommand(Unknown("4.2"), Value("")))) + } yield assert(result)(equalTo(RespCommand(Value("4.2"), Value("")))) }, test("with negative score and empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(-4.2d, ""))) - } yield assert(result)(equalTo(RespCommand(Unknown("-4.2"), Value("")))) + } yield assert(result)(equalTo(RespCommand(Value("-4.2"), Value("")))) }, test("with zero score and empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(0d, ""))) - } yield assert(result)(equalTo(RespCommand(Unknown("0.0"), Value("")))) + } yield assert(result)(equalTo(RespCommand(Value("0.0"), Value("")))) }, test("with positive score and non-empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(4.2d, "member"))) - } yield assert(result)(equalTo(RespCommand(Unknown("4.2"), Value("member")))) + } yield assert(result)(equalTo(RespCommand(Value("4.2"), Value("member")))) }, test("with negative score and non-empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(-4.2d, "member"))) - } yield assert(result)(equalTo(RespCommand(Unknown("-4.2"), Value("member")))) + } yield assert(result)(equalTo(RespCommand(Value("-4.2"), Value("member")))) }, test("with zero score and non-empty member") { for { result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(0d, "member"))) - } yield assert(result)(equalTo(RespCommand(Unknown("0.0"), Value("member")))) + } yield assert(result)(equalTo(RespCommand(Value("0.0"), Value("member")))) } ), suite("NoInput")( @@ -651,80 +651,80 @@ object InputSpec extends BaseSpec { test("with multiple elements") { for { result <- ZIO.attempt(NonEmptyList(StringInput).encode(("a", List("b", "c")))) - } yield assert(result)(equalTo(RespCommand(Unknown("a"), Unknown("b"), Unknown("c")))) + } yield assert(result)(equalTo(RespCommand(Value("a"), Value("b"), Value("c")))) }, test("with one element") { for { result <- ZIO.attempt(NonEmptyList(StringInput).encode(("a", List.empty))) - } yield assert(result)(equalTo(RespCommand(Unknown("a")))) + } yield assert(result)(equalTo(RespCommand(Value("a")))) } ), suite("Order")( test("ascending") { for { result <- ZIO.attempt(OrderInput.encode(Ascending)) - } yield assert(result)(equalTo(RespCommand(Unknown("ASC")))) + } yield assert(result)(equalTo(RespCommand(Value("ASC")))) }, test("descending") { for { result <- ZIO.attempt(OrderInput.encode(Descending)) - } yield assert(result)(equalTo(RespCommand(Unknown("DESC")))) + } yield assert(result)(equalTo(RespCommand(Value("DESC")))) } ), suite("RadiusUnit")( test("meters") { for { result <- ZIO.attempt(RadiusUnitInput.encode(Meters)) - } yield assert(result)(equalTo(RespCommand(Unknown("m")))) + } yield assert(result)(equalTo(RespCommand(Value("m")))) }, test("kilometers") { for { result <- ZIO.attempt(RadiusUnitInput.encode(Kilometers)) - } yield assert(result)(equalTo(RespCommand(Unknown("km")))) + } yield assert(result)(equalTo(RespCommand(Value("km")))) }, test("feet") { for { result <- ZIO.attempt(RadiusUnitInput.encode(Feet)) - } yield assert(result)(equalTo(RespCommand(Unknown("ft")))) + } yield assert(result)(equalTo(RespCommand(Value("ft")))) }, test("miles") { for { result <- ZIO.attempt(RadiusUnitInput.encode(Miles)) - } yield assert(result)(equalTo(RespCommand(Unknown("mi")))) + } yield assert(result)(equalTo(RespCommand(Value("mi")))) } ), suite("Range")( test("with positive start and positive end") { for { result <- ZIO.attempt(RangeInput.encode(Range(1, 5))) - } yield assert(result)(equalTo(RespCommand(Unknown("1"), Unknown("5")))) + } yield assert(result)(equalTo(RespCommand(Value("1"), Value("5")))) }, test("with negative start and positive end") { for { result <- ZIO.attempt(RangeInput.encode(Range(-1, 5))) - } yield assert(result)(equalTo(RespCommand(Unknown("-1"), Unknown("5")))) + } yield assert(result)(equalTo(RespCommand(Value("-1"), Value("5")))) }, test("with positive start and negative end") { for { result <- ZIO.attempt(RangeInput.encode(Range(1, -5))) - } yield assert(result)(equalTo(RespCommand(Unknown("1"), Unknown("-5")))) + } yield assert(result)(equalTo(RespCommand(Value("1"), Value("-5")))) }, test("with negative start and negative end") { for { result <- ZIO.attempt(RangeInput.encode(Range(-1, -5))) - } yield assert(result)(equalTo(RespCommand(Unknown("-1"), Unknown("-5")))) + } yield assert(result)(equalTo(RespCommand(Value("-1"), Value("-5")))) } ), suite("Pattern")( test("with valid pattern") { for { result <- ZIO.attempt(PatternInput.encode(Pattern("*[ab]-*"))) - } yield assert(result)(equalTo(RespCommand(Literal("MATCH"), Unknown("*[ab]-*")))) + } yield assert(result)(equalTo(RespCommand(Literal("MATCH"), Value("*[ab]-*")))) }, test("with empty pattern") { for { result <- ZIO.attempt(PatternInput.encode(Pattern(""))) - } yield assert(result)(equalTo(RespCommand(Literal("MATCH"), Unknown("")))) + } yield assert(result)(equalTo(RespCommand(Literal("MATCH"), Value("")))) } ), suite("Replace")( @@ -738,24 +738,24 @@ object InputSpec extends BaseSpec { test("with non-empty string") { for { result <- ZIO.attempt(StoreDistInput.encode(StoreDist("key"))) - } yield assert(result)(equalTo(RespCommand(Literal("STOREDIST"), Unknown("key")))) + } yield assert(result)(equalTo(RespCommand(Literal("STOREDIST"), Value("key")))) }, test("with empty string") { for { result <- ZIO.attempt(StoreDistInput.encode(StoreDist(""))) - } yield assert(result)(equalTo(RespCommand(Literal("STOREDIST"), Unknown("")))) + } yield assert(result)(equalTo(RespCommand(Literal("STOREDIST"), Value("")))) } ), suite("Store")( test("with non-empty string") { for { result <- ZIO.attempt(StoreInput.encode(Store("key"))) - } yield assert(result)(equalTo(RespCommand(Literal("STORE"), Unknown("key")))) + } yield assert(result)(equalTo(RespCommand(Literal("STORE"), Value("key")))) }, test("with empty string") { for { result <- ZIO.attempt(StoreInput.encode(Store(""))) - } yield assert(result)(equalTo(RespCommand(Literal("STORE"), Unknown("")))) + } yield assert(result)(equalTo(RespCommand(Literal("STORE"), Value("")))) } ), suite("ScoreRange")( @@ -865,12 +865,12 @@ object InputSpec extends BaseSpec { test("non-empty value") { for { result <- ZIO.attempt(StringInput.encode("non-empty")) - } yield assert(result)(equalTo(RespCommand(Unknown("non-empty")))) + } yield assert(result)(equalTo(RespCommand(Value("non-empty")))) }, test("empty value") { for { result <- ZIO.attempt(StringInput.encode("")) - } yield assert(result)(equalTo(RespCommand(Unknown("")))) + } yield assert(result)(equalTo(RespCommand(Value("")))) } ), suite("Optional")( @@ -882,62 +882,62 @@ object InputSpec extends BaseSpec { test("some") { for { result <- ZIO.attempt(OptionalInput(LongInput).encode(Some(2L))) - } yield assert(result)(equalTo(RespCommand(Unknown("2")))) + } yield assert(result)(equalTo(RespCommand(Value("2")))) } ), suite("TimeSeconds")( test("positiv value") { for { result <- ZIO.attempt(TimeSecondsInput.encode(Instant.ofEpochSecond(3L))) - } yield assert(result)(equalTo(RespCommand(Unknown("3")))) + } yield assert(result)(equalTo(RespCommand(Value("3")))) }, test("zero value") { for { result <- ZIO.attempt(TimeSecondsInput.encode(Instant.ofEpochSecond(0L))) - } yield assert(result)(equalTo(RespCommand(Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Value("0")))) }, test("negative value") { for { result <- ZIO.attempt(TimeSecondsInput.encode(Instant.ofEpochSecond(-3L))) - } yield assert(result)(equalTo(RespCommand(Unknown("-3")))) + } yield assert(result)(equalTo(RespCommand(Value("-3")))) } ), suite("TimeMilliseconds")( test("positiv value") { for { result <- ZIO.attempt(TimeMillisecondsInput.encode(Instant.ofEpochSecond(3L))) - } yield assert(result)(equalTo(RespCommand(Unknown("3000")))) + } yield assert(result)(equalTo(RespCommand(Value("3000")))) }, test("zero value") { for { result <- ZIO.attempt(TimeMillisecondsInput.encode(Instant.ofEpochSecond(0L))) - } yield assert(result)(equalTo(RespCommand(Unknown("0")))) + } yield assert(result)(equalTo(RespCommand(Value("0")))) }, test("negative value") { for { result <- ZIO.attempt(TimeMillisecondsInput.encode(Instant.ofEpochSecond(-3L))) - } yield assert(result)(equalTo(RespCommand(Unknown("-3000")))) + } yield assert(result)(equalTo(RespCommand(Value("-3000")))) } ), suite("Tuple2")( test("valid value") { for { result <- ZIO.attempt(Tuple2(StringInput, LongInput).encode(("one", 2L))) - } yield assert(result)(equalTo(RespCommand(Unknown("one"), Unknown("2")))) + } yield assert(result)(equalTo(RespCommand(Value("one"), Value("2")))) } ), suite("Tuple3")( test("valid value") { for { result <- ZIO.attempt(Tuple3(StringInput, LongInput, StringInput).encode(("one", 2, "three"))) - } yield assert(result)(equalTo(RespCommand(Unknown("one"), Unknown("2"), Unknown("three")))) + } yield assert(result)(equalTo(RespCommand(Value("one"), Value("2"), Value("three")))) } ), suite("Tuple4")( test("valid value") { for { result <- ZIO.attempt(Tuple4(StringInput, LongInput, StringInput, LongInput).encode(("one", 2, "three", 4))) - } yield assert(result)(equalTo(RespCommand(Unknown("one"), Unknown("2"), Unknown("three"), Unknown("4")))) + } yield assert(result)(equalTo(RespCommand(Value("one"), Value("2"), Value("three"), Value("4")))) } ), suite("Tuple5")( @@ -948,7 +948,7 @@ object InputSpec extends BaseSpec { .encode(("one", 2, "three", 4, "five")) ) } yield assert(result)( - equalTo(RespCommand(Unknown("one"), Unknown("2"), Unknown("three"), Unknown("4"), Unknown("five"))) + equalTo(RespCommand(Value("one"), Value("2"), Value("three"), Value("4"), Value("five"))) ) } ), @@ -962,13 +962,13 @@ object InputSpec extends BaseSpec { } yield assert(result)( equalTo( RespCommand( - Unknown("one"), - Unknown("2"), - Unknown("three"), - Unknown("4"), - Unknown("five"), - Unknown("6"), - Unknown("seven") + Value("one"), + Value("2"), + Value("three"), + Value("4"), + Value("five"), + Value("6"), + Value("seven") ) ) ) @@ -993,15 +993,15 @@ object InputSpec extends BaseSpec { } yield assert(result)( equalTo( RespCommand( - Unknown("one"), - Unknown("2"), - Unknown("three"), - Unknown("4"), - Unknown("five"), - Unknown("6"), - Unknown("seven"), - Unknown("8"), - Unknown("nine") + Value("one"), + Value("2"), + Value("three"), + Value("4"), + Value("five"), + Value("6"), + Value("seven"), + Value("8"), + Value("nine") ) ) ) @@ -1028,17 +1028,17 @@ object InputSpec extends BaseSpec { } yield assert(result)( equalTo( RespCommand( - Unknown("one"), - Unknown("2"), - Unknown("three"), - Unknown("4"), - Unknown("five"), - Unknown("6"), - Unknown("seven"), - Unknown("8"), - Unknown("nine"), - Unknown("10"), - Unknown("eleven") + Value("one"), + Value("2"), + Value("three"), + Value("4"), + Value("five"), + Value("6"), + Value("seven"), + Value("8"), + Value("nine"), + Value("10"), + Value("eleven") ) ) ) @@ -1048,32 +1048,32 @@ object InputSpec extends BaseSpec { test("set existing") { for { result <- ZIO.attempt(UpdateInput.encode(Update.SetExisting)) - } yield assert(result)(equalTo(RespCommand(Unknown("XX")))) + } yield assert(result)(equalTo(RespCommand(Value("XX")))) }, test("set new") { for { result <- ZIO.attempt(UpdateInput.encode(Update.SetNew)) - } yield assert(result)(equalTo(RespCommand(Unknown("NX")))) + } yield assert(result)(equalTo(RespCommand(Value("NX")))) } ), suite("Id")( test("valid value") { for { result <- ZIO.attempt(IdInput.encode(10)) - } yield assert(result)(equalTo(RespCommand(Literal("ID"), Unknown("10")))) + } yield assert(result)(equalTo(RespCommand(Literal("ID"), Value("10")))) } ), suite("IDs")( test("with a single element") { for { result <- ZIO.attempt(IdsInput.encode((1, Nil))) - } yield assert(result)(equalTo(RespCommand(Literal("ID"), Unknown("1")))) + } yield assert(result)(equalTo(RespCommand(Literal("ID"), Value("1")))) }, test("with multiple elements") { for { result <- ZIO.attempt(IdsInput.encode((1, List(2, 3, 4)))) } yield assert(result)( - equalTo(RespCommand(Literal("ID"), Unknown("1"), Unknown("2"), Unknown("3"), Unknown("4"))) + equalTo(RespCommand(Literal("ID"), Value("1"), Value("2"), Value("3"), Value("4"))) ) } ), @@ -1081,19 +1081,19 @@ object InputSpec extends BaseSpec { test("timeout") { for { result <- ZIO.attempt(UnblockBehaviorInput.encode(UnblockBehavior.Timeout)) - } yield assert(result)(equalTo(RespCommand(Unknown("TIMEOUT")))) + } yield assert(result)(equalTo(RespCommand(Value("TIMEOUT")))) }, test("error") { for { result <- ZIO.attempt(UnblockBehaviorInput.encode(UnblockBehavior.Error)) - } yield assert(result)(equalTo(RespCommand(Unknown("ERROR")))) + } yield assert(result)(equalTo(RespCommand(Value("ERROR")))) } ), suite("Varargs")( test("with multiple elements") { for { result <- ZIO.attempt(Varargs(LongInput).encode(List(1, 2, 3))) - } yield assert(result)(equalTo(RespCommand(Unknown("1"), Unknown("2"), Unknown("3")))) + } yield assert(result)(equalTo(RespCommand(Value("1"), Value("2"), Value("3")))) }, test("with no elements") { for { @@ -1133,46 +1133,46 @@ object InputSpec extends BaseSpec { test("with 1 second") { ZIO .attempt(IdleInput.encode(1.second)) - .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Unknown("1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Value("1000"))))) }, test("with 100 milliseconds") { ZIO .attempt(IdleInput.encode(100.millis)) - .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Unknown("100"))))) + .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Value("100"))))) }, test("with negative duration") { ZIO .attempt(IdleInput.encode((-1).second)) - .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Unknown("-1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("IDLE"), Value("-1000"))))) } ), suite("Time")( test("with 1 second") { ZIO .attempt(TimeInput.encode(1.second)) - .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Unknown("1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Value("1000"))))) }, test("with 100 milliseconds") { ZIO .attempt(TimeInput.encode(100.millis)) - .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Unknown("100"))))) + .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Value("100"))))) }, test("with negative duration") { ZIO .attempt(TimeInput.encode((-1).second)) - .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Unknown("-1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("TIME"), Value("-1000"))))) } ), suite("RetryCount")( test("with positive count") { ZIO .attempt(RetryCountInput.encode(100)) - .map(assert(_)(equalTo(RespCommand(Literal("RETRYCOUNT"), Unknown("100"))))) + .map(assert(_)(equalTo(RespCommand(Literal("RETRYCOUNT"), Value("100"))))) }, test("with negative count") { ZIO .attempt(RetryCountInput.encode(-100)) - .map(assert(_)(equalTo(RespCommand(Literal("RETRYCOUNT"), Unknown("-100"))))) + .map(assert(_)(equalTo(RespCommand(Literal("RETRYCOUNT"), Value("-100"))))) } ), suite("XGroupCreate")( @@ -1183,7 +1183,7 @@ object InputSpec extends BaseSpec { XGroupCommand.Create("key", "group", "id", mkStream = false) ) ) - .map(assert(_)(equalTo(RespCommand(Literal("CREATE"), Key("key"), Unknown("group"), Unknown("id"))))) + .map(assert(_)(equalTo(RespCommand(Literal("CREATE"), Key("key"), Value("group"), Value("id"))))) }, test("with mkStream") { ZIO @@ -1195,7 +1195,7 @@ object InputSpec extends BaseSpec { .map( assert(_)( equalTo( - RespCommand(Literal("CREATE"), Key("key"), Unknown("group"), Unknown("id"), Literal("MKSTREAM")) + RespCommand(Literal("CREATE"), Key("key"), Value("group"), Value("id"), Literal("MKSTREAM")) ) ) ) @@ -1205,14 +1205,14 @@ object InputSpec extends BaseSpec { test("valid value") { ZIO .attempt(XGroupSetIdInput[String, String, String]().encode(XGroupCommand.SetId("key", "group", "id"))) - .map(assert(_)(equalTo(RespCommand(Literal("SETID"), Key("key"), Unknown("group"), Unknown("id"))))) + .map(assert(_)(equalTo(RespCommand(Literal("SETID"), Key("key"), Value("group"), Value("id"))))) } ), suite("XGroupDestroy")( test("valid value") { ZIO .attempt(XGroupDestroyInput[String, String]().encode(XGroupCommand.Destroy("key", "group"))) - .map(assert(_)(equalTo(RespCommand(Literal("DESTROY"), Key("key"), Unknown("group"))))) + .map(assert(_)(equalTo(RespCommand(Literal("DESTROY"), Key("key"), Value("group"))))) } ), suite("XGroupCreateConsumer")( @@ -1225,7 +1225,7 @@ object InputSpec extends BaseSpec { ) .map( assert(_)( - equalTo(RespCommand(Literal("CREATECONSUMER"), Key("key"), Unknown("group"), Unknown("consumer"))) + equalTo(RespCommand(Literal("CREATECONSUMER"), Key("key"), Value("group"), Value("consumer"))) ) ) } @@ -1239,7 +1239,7 @@ object InputSpec extends BaseSpec { ) ) .map( - assert(_)(equalTo(RespCommand(Literal("DELCONSUMER"), Key("key"), Unknown("group"), Unknown("consumer")))) + assert(_)(equalTo(RespCommand(Literal("DELCONSUMER"), Key("key"), Value("group"), Value("consumer")))) ) } ), @@ -1247,17 +1247,17 @@ object InputSpec extends BaseSpec { test("with 1 second") { ZIO .attempt(BlockInput.encode(1.second)) - .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Unknown("1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Value("1000"))))) }, test("with 100 milliseconds") { ZIO .attempt(BlockInput.encode(100.millis)) - .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Unknown("100"))))) + .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Value("100"))))) }, test("with negative duration") { ZIO .attempt(BlockInput.encode((-1).second)) - .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Unknown("-1000"))))) + .map(assert(_)(equalTo(RespCommand(Literal("BLOCK"), Value("-1000"))))) } ), suite("Streams")( @@ -1274,19 +1274,19 @@ object InputSpec extends BaseSpec { ), suite("NoAck")( test("valid value") { - ZIO.attempt(NoAckInput.encode(NoAck)).map(assert(_)(equalTo(RespCommand(Unknown("NOACK"))))) + ZIO.attempt(NoAckInput.encode(NoAck)).map(assert(_)(equalTo(RespCommand(Value("NOACK"))))) } ), suite("MaxLen")( test("with approximate") { ZIO .attempt(StreamMaxLenInput.encode(StreamMaxLen(approximate = true, 10))) - .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Literal("~"), Unknown("10"))))) + .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Literal("~"), Value("10"))))) }, test("without approximate") { ZIO .attempt(StreamMaxLenInput.encode(StreamMaxLen(approximate = false, 10))) - .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Unknown("10"))))) + .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Value("10"))))) } ), suite("WithForce")( @@ -1315,12 +1315,12 @@ object InputSpec extends BaseSpec { test("valid value") { ZIO .attempt(ListMaxLenInput.encode(ListMaxLen(10L))) - .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Unknown("10"))))) + .map(assert(_)(equalTo(RespCommand(Literal("MAXLEN"), Value("10"))))) } ), suite("Rank")( test("valid value") { - ZIO.attempt(RankInput.encode(Rank(10L))).map(assert(_)(equalTo(RespCommand(Literal("RANK"), Unknown("10"))))) + ZIO.attempt(RankInput.encode(Rank(10L))).map(assert(_)(equalTo(RespCommand(Literal("RANK"), Value("10"))))) } ), suite("GetEx")( @@ -1330,10 +1330,10 @@ object InputSpec extends BaseSpec { ZIO.attempt(GetExInput[String]().encode(scala.Tuple3.apply("key", Expire.SetExpireSeconds, 1.second))) resultMilliseconds <- ZIO.attempt(GetExInput[String]().encode(scala.Tuple3("key", Expire.SetExpireMilliseconds, 100.millis))) - } yield assert(resultSeconds)(equalTo(RespCommand(Key("key"), Literal("EX"), Unknown("1")))) && assert( + } yield assert(resultSeconds)(equalTo(RespCommand(Key("key"), Literal("EX"), Value("1")))) && assert( resultMilliseconds )( - equalTo(RespCommand(Key("key"), Literal("PX"), Unknown("100"))) + equalTo(RespCommand(Key("key"), Literal("PX"), Value("100"))) ) }, test("GetExAtInput - valid value") { @@ -1351,9 +1351,9 @@ object InputSpec extends BaseSpec { ) ) } yield assert(resultSeconds)( - equalTo(RespCommand(Key("key"), Literal("EXAT"), Unknown("1617667200"))) + equalTo(RespCommand(Key("key"), Literal("EXAT"), Value("1617667200"))) ) && assert(resultMilliseconds)( - equalTo(RespCommand(Key("key"), Literal("PXAT"), Unknown("1617667200000"))) + equalTo(RespCommand(Key("key"), Literal("PXAT"), Value("1617667200000"))) ) }, test("GetExPersistInput - valid value") { -- GitLab