I'm trying to write a custom pickler to handle java.util.Date
by converting to/from an ISO8601 date string. What I have is this:
case class JSONDate(date: Date) extends AnyVal
object JSONDate {
implicit def readWrite: ReadWriter[JSONDate] = readwriter[ujson.Value].bimap[JSONDate](
(date: JSONDate) => DateTimeFormatter.ISO_INSTANT.format(date.date.toInstant),
(json: ujson.Value) => JSONDate(Date.from(OffsetDateTime.parse(json.str).toInstant))
)
}
But whilst this works:
val d: JSONDate = JSONDate(comp.getTimeCreated)
write(d)
This doesn't:
write(ujson.Obj(
"Name" -> "myName",
"Created" -> d
))
For some reason the implicit isn't being found in the ujson.Obj
case. Any suggestions?
The release notes for 0.5.1 say:
ujson.write now takes an optional `sortKeys` flag, if you want the JSON dictionaries to rendered in a standardized order
But that doesn't seem to exist any more. How do I ensure that Object keys are sorted? This is to make it easier to compare versions of a JSON file in a diff tool...
I see ujson.Obj
uses a LinkedHashMap
so it will preserve insertion order. Rather than sorting into a new Obj
when the contents have all been added I could do a two-step process but it's still a bit clunky as it requires a Map
copy:
val sortedMap = mutable.SortedMap[String, ujson.Value]()
addSomeStuffWithUnpredictableKeyOrdering(sortedMap)
val obj = ujson.Obj.from(sortedMap)
What would be nice is if Obj
could be configured to use either mutable.LinkedHashMap
as at present, or mutable.SortedMap
- then you could choose to either preserve insertion order, or have ordering by key.
ujson.Obj
could hold a reference of a mutable.Map[String, ujson.Value]
instead of a mutable.LinkedHashMap[String, ujson.Value]
.mutable.LinkedHashMap[String, ujson.Value]
and you could pass a different type of map by doing:val myMap = mutable.SortedMap[String, ujson.Value]()
val obj = new ujson.Obj(myMap)
@lolgab well, you shouldn't really be depending on map key ordering in the first place I suppose, but you already get that with the current implementation ;-)
I'd settle for being able to specify ordering during write
, again I know you shouldn't do that with JSON but it does make it easier to process with existing diff tools...
visitObject
, and does this:
def visitKeyValue(s: Any): Unit = {
lastNested.visitValue(s.asInstanceOf[T], lastKeyIndex)
}
However, nobody set lastNested
, so it's now null... Should I not use this call, and/or use visitKey first?
"id""
.visitKey(-1)
everywhere before .visitKeyValue
... this seems to solve it :)
case class Thing(myFieldA: Int, myFieldB: String)
object Thing{
implicit val rw: RW[Thing] = macroRW
}
case class Big(i: Int, b: Boolean, str: String, c: Char, t: Thing)
object Big{
implicit val rw: RW[Big] = macroRW
}
object TestClient {
def main(args: Array[String]): Unit = {
read[Thing]("""{"myFieldA":1,"myFieldB":"gg"}""")
}
}
Gives me an error and suggests to import upickle.legacy.read
no implicit argument of type upickle.legacy.Reader[Thing] was found for an implicit parameter of method read in trait Api.
I found: upickle.legacy.given_Reader_T[T](/* missing */summon[deriving.Mirror.Of[T]])
But no implicit values were found that match type deriving.Mirror.Of[T].
https://github.com/objektwerks/scala3.json
. The most recent test uses Scala 3 and uPickle 2.0.0. Has anyone else noticed this performance change?