Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema based header codecs, unified with query codecs (#3232) #3270

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

987Nabil
Copy link
Contributor

@987Nabil 987Nabil commented Jan 9, 2025

Fix for publish CI job

fixes #3232
/claim #3232

fixes #3255
fixes #3240

@987Nabil 987Nabil requested review from jdegoes and vigoo as code owners January 9, 2025 22:22
@987Nabil 987Nabil force-pushed the header-codec-restructure branch 7 times, most recently from e69771b to 0bb55d3 Compare January 13, 2025 09:24
@987Nabil 987Nabil force-pushed the header-codec-restructure branch from 0bb55d3 to c9c2c22 Compare January 13, 2025 14:15
@@ -2409,7 +2494,34 @@ object HttpCodec extends ContentCodecs with HeaderCodecs with MethodCodecs with
def index(index: Int): Method[A] = copy(index = index)
}

private[http] final case class Header[A](name: String, textCodec: TextCodec[A], index: Int = 0)
private[http] final case class HeaderCustom[A](codec: SchemaCodec[A], index: Int = 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this just the same as name = None?

import zio.http.Charsets

object StringCodec {
type StringCodec[A] = Codec[String, Char, A]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather put this in a final case class StringCodec(codec: Codec[String, Char, A]) than have a type alias for it.

Remind me why we need this?

}
}

implicit def fromSchema[A](implicit schema: Schema[A]): Codec[String, Char, A] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this whole thing as Schema#toString(value) and Schema#fromString(string)?? Why does this even belong here?

case HttpCodec.AtomTag.Content => copy(content = f(content))
case HttpCodec.AtomTag.Query => copy(query = f(query))
case HttpCodec.AtomTag.Header => copy(header = f(header))
case HttpCodec.AtomTag.HeaderCustom => copy(headerCustom = f(header))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's painful to see Header and HeaderCustom when all the other cases just have a single codec!

.unsafeQueryParam(name) == "" && !emptyStringIsValue(codec.codec.schema))) && hasDefault
)
default
else if (!hasParam)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This complicated and fragile code suggests one way to refactor this is as a method on the query codec which returns a sealed trait containing the right information.

In other words, instead of, if (isA) then extractA else if (isB) then extractB, you can just have a thing match { case A(a) => ... }

else decoded
}

} else if (codec.isCollection) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely need to adopt the above pattern to deal with this. Some pre-analysis with pre-collection of required information, packaged into a sealed trait.

}
validateDecoded(codec, decoded)
}
if (optional) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto for all this.

Copy link
Member

@jdegoes jdegoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very close, though there is some cleanup I'd like to see happen before merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants