-
Notifications
You must be signed in to change notification settings - Fork 532
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
Snake Case (or any Configuration-related problem) with Scala 3 #1694
Comments
You could use |
Right, I think unfortunately right now your best bet on Scala 3 is something like this (tested on Scala 3): scala> import io.circe.{Encoder, JsonObject}, io.circe.generic.semiauto.deriveEncoder
scala> import java.util.regex.Pattern
scala> val snakeCaseTransformation: String => String = s => {
| val basePattern: Pattern = Pattern.compile("([A-Z]+)([A-Z][a-z])")
| val swapPattern: Pattern = Pattern.compile("([a-z\\d])([A-Z])")
| val partial = basePattern.matcher(s).replaceAll("$1_$2")
| swapPattern.matcher(partial).replaceAll("$1_$2").toLowerCase
| }
val snakeCaseTransformation: String => String = Lambda$6404/700040865@2b523359
scala> def snakeCaseIfy[A](encoder: Encoder.AsObject[A]): Encoder.AsObject[A] =
| encoder.mapJsonObject(obj =>
| JsonObject.fromIterable(obj.toIterable.map {
| case (k, v) => (snakeCaseTransformation(k), v) }
| )
| )
|
def snakeCaseIfy
[A](encoder: io.circe.Encoder.AsObject[A]): io.circe.Encoder.AsObject[A]
scala> case class Foo(firstName: String, lastName: String)
// defined case class Foo
scala> implicit val encoderFoo: Encoder.AsObject[Foo] = snakeCaseIfy(deriveEncoder)
val encoderFoo: io.circe.Encoder.AsObject[Foo] = io.circe.Encoder$$anon$66@717a0dd4
scala> import io.circe.syntax._
scala> Foo("Foo", "McBar").asJson
val res0: io.circe.Json = {
"first_name" : "Foo",
"last_name" : "McBar"
} |
Awesome detailed help. |
I'm sorry I only exposed the Serialization issue although I obviously have deserialization ones. Is there a way to "unsakify" with a derivedDecoder? Edit: https://gitter.im/circe/circe?at=5d542e282612bb718c685031 this Something around these lines: private val snakePattern = "_([a-z\\d])".r
private val snakeToCamel: String => String = s => {
snakePattern.replaceAllIn(s, {m =>
m.group(1).toUpperCase()
})
}
private def unSnakeCaseIfy(o: JsonObject): JsonObject =
JsonObject.fromIterable(o.toVector.map {
case (k, v) => snakeToCamel(k) -> v
})
def unSnakeCaseIfy[A](decoder: Decoder[A]): Decoder[A] = (c: HCursor) => {
decoder.tryDecode(c.withFocus(_.mapObject(unSnakeCaseIfy)))
} |
Hello, and thank you for all the effort you're putting in Circe, and Scala 3 migration.
I tried to measure the amount of effort needed to migrate one of my projects to Scala3.
I'm struggling a bit with JSON serialization since it involves snake_case transformations on case class attributes.
I used to use circe-generic-extras with ConfiguredJsonObject but I saw it will probably not be updated to Scala3 anytime soon, which I can understand.
Is there any other way (other than writing an Encoder by hand) to obtain an Encoder that uses snake_case for case class attributes?
Like deriving an Encoder and "mapping it" in some way?
Sorry if the question isn't clear enough, but I'm trying to find a workaround for this, and thanks again for your time and effort.
The text was updated successfully, but these errors were encountered: