Created
August 23, 2016 14:22
-
-
Save sam/e28e7ea1d13215234fdcf6dde1991436 to your computer and use it in GitHub Desktop.
Example of a json4s Format for a sealed trait (Id) with two implementations (NewId or IdWithRev).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.json4s._ | |
case object IdSerializer extends CustomSerializer[Id](formats => ( { | |
case JObject(JField("prefix", JString(prefix)) :: JField("id", JString(id)) :: JField("rev", JString(rev)) :: Nil) => IdWithRev(prefix, id, rev) | |
case JObject(JField("prefix", JString(prefix)) :: JField("id", JString(id)) :: Nil) => NewId(prefix, id) | |
}, { | |
case NewId(prefix, id) => JObject(JField("prefix", JString(prefix)) :: JField("id", JString(id)) :: Nil) | |
case IdWithRev(prefix, id, rev) => JObject(JField("prefix", JString(prefix)) :: JField("id", JString(id)) :: JField("rev", JString(rev)) :: Nil) | |
} | |
)) |
This seems to work. It's basically just lifting the contents of the |||
operator and type-casting the fallback decoder:
val CodecNewId = casecodec2(NewId.apply, NewId.unapply)("prefix", "id")
val CodecIdWithRev = casecodec3(IdWithRev.apply, IdWithRev.unapply)("prefix", "id", "rev")
implicit val CodecId: CodecJson[Id] =
CodecJson.derived[Id](
EncodeJson {
case id: NewId => CodecNewId(id)
case id: IdWithRev => CodecIdWithRev(id)
},
DecodeJson[Id](c => {
val q = CodecIdWithRev(c).map(a => a: Id)
q.result.fold(_ => CodecNewId(c).map(a => a: Id), _ => q)
})
)
There's got to be a prettier way to do this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This doesn't work in argonaut: