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

Snake case behavior does not match play-json #82

Open
dforciea opened this issue Aug 14, 2020 · 3 comments
Open

Snake case behavior does not match play-json #82

dforciea opened this issue Aug 14, 2020 · 3 comments

Comments

@dforciea
Copy link

I was trying to update from using the tototoshi json naming library to using the built-in snake case facility. However, I found out that the behavior of play-json-extensions does not match that or what is in the main play-json library. I think that it would make the most sense if this exactly matched the main play library.

I think the issue lies in how numbers are treated.
play-json would snake case foo12Bar as foo12_bar
play-json-extensions would snake case foo12Bar as foo_1_2_bar

I suggest just having play-json-extensions just delegate to the play library, since the snake case function is public:
https://github.com/playframework/play-json/blob/2.8.1/play-json/shared/src/main/scala/play/api/libs/json/JsonConfiguration.scala#L99

@JR-Utily
Copy link

I have same issue.

Here is a quick test to demonstrate that


 case class AAA (
      variableWith1Element: String,
      aaa3E: String
  )

  object AAA {
    val formatPlay: Format[AAA] = {
      implicit val config: Aux[WithDefaultValues] = JsonConfiguration[WithDefaultValues](SnakeCase)
      Json.format[AAA]
    }
    val formatJsonX: Format[AAA] = {
      implicit val encoder: NameEncoder = CamelToSnakeNameEncoder()
      Jsonx.formatCaseClass[AAA]
    }
  }

  "aaa" should "des/ser"  in {
    val aaa= AAA("a","b")

    val jsonPlay = Json.parse( """{"variable_with1_element":"a", "aaa3_e":"b"}""" )
    val jsonX = Json.parse( """{"variable_with_1_element":"a", "aaa_3_e":"b"}""" )
    
    {
      implicit val format: Format[AAA] = AAA.formatPlay
      assert( aaa === jsonPlay.as[AAA] )
      assert( Json.toJson( aaa ) === jsonPlay )
    }

    {
      implicit val format: Format[AAA] = AAA.formatJsonX
      assert( aaa === jsonX.as[AAA] )
      assert( Json.toJson( aaa ) === jsonX )
    }
  }

I'd love to make my own NameEncoder, but sadly it is a sealed trait I can't inherit from, so following code does not compile

object PlaySnakeCaseNameEncoder extends NameEncoder {
  override def encode(str: String): String =
    play.api.libs.json.JsonNaming.SnakeCase.apply(str)
}

@dforciea
Copy link
Author

dforciea commented Oct 9, 2020

@caente It looks like you're the committer who has done the most recent release - is there any particular set of instructions for making contributions to this repository? I just wanted to check in since I haven't heard anything in a couple of months.

@astiob
Copy link

astiob commented May 10, 2023

For reference, here’s how we’ve been working around this in our projects:

import ai.x.play.json.{CamelToSnakeNameEncoder, NameEncoder}
import play.api.libs.json.JsonNaming.SnakeCase

implicit val encoder: NameEncoder = new CamelToSnakeNameEncoder {
  // Stock CamelToSnakeNameEncoder behaves differently from SnakeCase:
  // see https://github.com/xdotai/play-json-extensions/issues/82
  override def encode(str: String): String = SnakeCase(str)
}

NameEncoder may be sealed, but CamelToSnakeNameEncoder isn’t.

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

Successfully merging a pull request may close this issue.

3 participants