Skip to content

Commit

Permalink
TextCodec.SeqCodec
Browse files Browse the repository at this point in the history
  • Loading branch information
eshu committed Oct 7, 2023
1 parent de31152 commit 578526d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 24 deletions.
18 changes: 17 additions & 1 deletion zio-http/src/main/scala/zio/http/codec/TextCodec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

package zio.http.codec

import java.util.UUID
import zio.Chunk

import java.util.UUID
import zio.stacktracer.TracingImplicits.disableAutoTrace

/**
Expand Down Expand Up @@ -59,6 +60,8 @@ object TextCodec {

implicit val uuid: TextCodec[UUID] = UUIDCodec

implicit def seq[A](implicit scalarCodec: TextCodec[A]): TextCodec[Chunk[A]] = SeqCodec(scalarCodec)

final case class Constant(string: String) extends TextCodec[Unit] {

def apply(value: String): Unit = if (value == string) () else throw new MatchError(value)
Expand Down Expand Up @@ -190,4 +193,17 @@ object TextCodec {
override def toString(): String = "TextCodec.uuid"
}

case class SeqCodec[A](scalarCodec: TextCodec[A]) extends TextCodec[Chunk[A]] {
override def apply(value: String): Chunk[A] = (scalarCodec andThen (Chunk(_)))(value)

// TODO Find a better naming
override def describe: String = s"a sequence of ${scalarCodec.describe}"

override def encode(value: Chunk[A]): String =
throw new NotImplementedError("encode is not implemented for SeqCodec")

override def isDefinedAt(value: String): Boolean = scalarCodec.isDefinedAt(value)

override def toString: String = s"TextCodec.seq[${scalarCodec.toString}]"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@
package zio.http.codec.internal

import zio._
import zio.stacktracer.TracingImplicits.disableAutoTrace

import zio.stream.ZStream

import zio.schema.Schema
import zio.schema.codec.{BinaryCodec, Codec}

import zio.http._
import zio.http.codec._
import zio.schema.Schema
import zio.schema.codec.{BinaryCodec, Codec}
import zio.stream.ZStream

private[codec] trait EncoderDecoder[-AtomTypes, Value] {
def decode(url: URL, status: Status, method: Method, headers: Headers, body: Body)(implicit
Expand Down Expand Up @@ -279,18 +275,21 @@ private[codec] object EncoderDecoder {
var i = 0
val queries = flattened.query
while (i < queries.length) {
val query = queries(i).erase

val queryParamValue =
queryParams
.getAllOrElse(query.name, Nil)
.collectFirst(query.textCodec)

queryParamValue match {
case Some(value) =>
inputs(i) = value
case None =>
throw HttpCodecError.MissingQueryParam(query.name)
val query = queries(i)

query.textCodec match {
case TextCodec.SeqCodec(scalarCodec) =>
queryParams
.getAllOrElse(query.name, Nil)
.map(value =>
if (scalarCodec.isDefinedAt(value)) scalarCodec(value)
else throw HttpCodecError.MalformedQueryParam(query.name, query.textCodec),
)
case scalarCodec =>
inputs(i) = queryParams
.getAllOrElse(query.name, Nil)
.collectFirst(scalarCodec)
.getOrElse(throw HttpCodecError.MissingQueryParam(query.name))
}

i = i + 1
Expand Down Expand Up @@ -475,12 +474,14 @@ private[codec] object EncoderDecoder {

var i = 0
while (i < inputs.length) {
val query = flattened.query(i).erase
val query = flattened.query(i) // .erase
val input = inputs(i)

val value = query.textCodec.encode(input)

queryParams = queryParams.add(query.name, value)
queryParams = query.textCodec match {
case TextCodec.SeqCodec(scalarCodec) =>
queryParams.addAll(query.name, input.asInstanceOf[Chunk[?]].map(scalarCodec.erase.encode))
case scalarCodec => queryParams.add(query.name, scalarCodec.erase.encode(input))
}

i = i + 1
}
Expand Down

0 comments on commit 578526d

Please sign in to comment.