Ah, a simpler answer. The macros are more specific than the classtag. So even though the macro is giving the correct type, the classtag that is implicitly carried is not specific to the enum instance
CLASS NAME: upickle.EnumTests.SimpleEnum.B Classtag: upickle.EnumTests$SimpleEnum
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].