Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 30 2019 12:25
    justdoit0823 starred json4s/json4s
  • Jan 30 2019 11:05
    ericxsun commented #212
  • Jan 26 2019 13:29

    seratch on v3.6.4

    (compare)

  • Jan 26 2019 13:28

    seratch on 3.6

    version 3.6.4 Start 3.6.5 dev (compare)

  • Jan 26 2019 12:53

    seratch on 3.6

    Reduced OrElse objects allocati… Merge branch '3.6' into pr-580-… Merge branch '3.6' into pr-580-… and 1 more (compare)

  • Jan 26 2019 12:53
    seratch closed #582
  • Jan 26 2019 12:39
    seratch synchronize #582
  • Jan 26 2019 12:39

    seratch on 3.6

    fix Type alias for parameterize… Merge branch '3.6' into pr-577-… Merge pull request #581 from se… (compare)

  • Jan 26 2019 12:39
    seratch closed #581
  • Jan 26 2019 12:38
    seratch synchronize #582
  • Jan 26 2019 12:38
    seratch opened #582
  • Jan 26 2019 12:30
    seratch synchronize #581
  • Jan 26 2019 12:30

    seratch on 3.6

    Add 3.6.3 to previous versions … (compare)

  • Jan 26 2019 12:25

    seratch on master

    Reduced OrElse objects allocati… (compare)

  • Jan 26 2019 12:25
    seratch closed #580
  • Jan 26 2019 12:25
    seratch closed #579
  • Jan 26 2019 12:25
    seratch commented #580
  • Jan 26 2019 11:03
    poslegm commented #580
  • Jan 26 2019 10:56
    poslegm synchronize #580
  • Jan 26 2019 10:32
    seratch commented #580
Stefan Ollinger
@dozed
It can decode a JSON array to a HList, iff there is a JSONR[T] in implicit scope for all its element types.
Sam Smoot
@sam
@dozed: I’m not all that familiar with HLists, but from what I can tell Every is a lot less ambitious. It’s basically just a Seq[T] that can’t be empty.
So if my application needs to support photos with several localized attributes I might:
object Photo {
  case class Localization(locale: Locale, title: String, caption: String)
}

case class Photo(id: String, file: File, localizations: Every[Photo.Localization])
Stefan Ollinger
@dozed
@sam You use extraction/decomposition?
Sam Smoot
@sam
Because I want to validate that a Photo must have a title, Every allows me to guarantee that a Photo will have at least one Localization. So it’s nice to encode that into the type-system IME. That’s how I use Every anyways. Which is just a sealed trait with common collection operations, and two implementations: case class One[T](entry: T) extends Every[T]or case class Many[T](first: T, rest: T*) extends Every[T].
Stefan Ollinger
@dozed
@sam This is the place where all the cases are handled where no CustomSerializer[T] is found: https://github.com/json4s/json4s/blob/3.4/core/src/main/scala/org/json4s/Extraction.scala#L146-L231
There is support for Iterable[A], Option[A] and Either[E, A].
Sam Smoot
@sam
@dozed: Sweet. Thanks.
Stefan Ollinger
@dozed
You want to supply a CustomSerializer[Every[A]] where the A is variable
This is not possible, the A must be given
Sam Smoot
@sam
@dozed Oh, and yeah. I use decompose(photo) and document.extract[Photo] in conjunction with https://github.com/hseeberger/akka-http-json/blob/master/akka-http-json4s/src/main/scala/de/heikoseeberger/akkahttpjson4s/Json4sSupport.scala to provide a basic akka-http Unmarshaller for JValues.
Stefan Ollinger
@dozed
The Formats has a list of those CustomSerializer[A] instances
Sam Smoot
@sam
dozed: I don’t have to provide A for any Option[A] I want though?
Stefan Ollinger
@dozed
Yes
Or better: you dont need to provide a CustomSerializer[Option[A]]
Sam Smoot
@sam
@dozed I see: https://github.com/json4s/json4s/blob/3.4/core/src/main/scala/org/json4s/Extraction.scala#L203 So basically generics get custom support there, and there’s not a way to handle new generic types transparently just by handling the container even if I have a format for A. That about sum it up? If I wanted to handle an Every[Photo.Localization], as well as Every[Video.Localization] I’d need implicit val formats = DefaultFormats + everyFormat[Photo.Localization]() + everyFormat[Video.Localization]() where def everyFormat[A](): CustomerSerializer[Every[A]] = ??? ?
Stefan Ollinger
@dozed
Yes, that is correct.
That is one benefit of the typeclass-based serialization, where you ask the compiler to resolve an instance for you
vs. creating a list of the instances
Sam Smoot
@sam
If so I’d say that maybe that’s another good reason to consider spray-json style typeclasses. :-) Maybe with the reflection-based serializers as a final fall-back. More like: implicit val formats = MyFormats.all ++ DefaultFormats.reflectionBased? Don’t want to seem ungrateful. I really like json4s overall. Just some opportunities to take the best ideas from others maybe.
Stefan Ollinger
@dozed
You dont need to be grateful ;)
What do you mean with DefaultFormats.reflectionBased ?
Sam Smoot
@sam
@dozed Haven’t dug into it, but imagined the automagic case-class support (so I didn’t have to say: implicit val photoFormat = jsonFormat6(Photo.apply)like spray-json for all my case-classes) was reflection-based. Ideally that wouldn’t go away and could be used as a fall-back. Even if it were optional. Maybe only recommended for quick prototyping or early development where your classes change frequently. :-)
It’s a minor annoyance in spray-json to have to change the jsonFormat6 to a jsonFormat7every time you add an addition field.
Stefan Ollinger
@dozed
Ok, I would definitely suggest choosing typeclass-based codecs
Stefan Ollinger
@dozed
Supporting Every[T] with the Formats approach is not trivial
With typeclasses you can declare an implicit def which has the constraint that there needs to be an instance of the typeclass for the "contained" type.
implicit def listJSONW[A: JSONW]: JSONW[List[A]] = new JSONW[List[A]] {
  def write(values: List[A]) = JArray(values.map(x => implicitly[JSONW[A]].write(x)))
}
E.g. like this.
A:JSONW says: there needs to be a JSONW[A]
And then the compiler can do the work
It is a lot clearer
@sam
Sam Smoot
@sam

@dozed How do you actually use the type class support?

> JSONW(User(“bob”, “password”))
res0: JObject(List(JField(“name”, JString(“bob”)), JField(“password”, JString(“password”))))

maybe?

Oh. No. That’s the typeclass. Never mind. Duh. Uhmm. Just write your own decompose[A: JSONW](value: A)?
Is the plan that json4s will have both forms going forward or is the type class one planned to obsolete Formats someday?
Stefan Ollinger
@dozed
A lot of existing code depends on json4s, so I think both forms will co-exist.
There is also not much in the docs yet about the alternatives.
Imo teaching people about Formats is not the most responsible thing
Sam Smoot
@sam
@dozed Hmm… it should be possible to write a CustomSerializer[ T : JSONW ] though actually right? That’s not a crazy idea maybe? And then if you have a JSONW[Every[T]], that could bridge it to your Formats?
Stefan Ollinger
@dozed
If you can get it to work, that would be nice
The fundamental difference is that with Formats the typeclass instances are stored in a list, whereas a standard typeclass approach would declare only dependencies via implicit parameters
Sam Smoot
@sam
I’ll need to figure something out in the next few days for my few cases of Every. I’ll let you know if anything comes of it. Or if I just have to fall-back to a factory method for different variations of def factory[A]() = new CustomerSerializer[Every[A]](…).
Stefan Ollinger
@dozed
And I am working currently here https://github.com/dozed/json4s-drafts/
Here is for example a JSONW/JSONR instance for NonEmptyList (which is similar to Every): https://github.com/dozed/json4s-drafts/blob/master/src/test/scala/TupleMaps1.scala#L19
Stefan Ollinger
@dozed
@sam The typeclasses are basically functions: A => JValue and JValue => Result[A]
Where Result[A] has two possible cases, Success(a) and Failure(errors)
eugene yokota
@eed3si9n
hi
Sam Smoot
@sam
howdy