Open cvogt opened 9 years ago
generalize:
implicit class FormatTagExtension[T](enclosed: Format[T]){ def tagWithType(implicit classTag: ClassTag[T]): Format[T] = new Format[T]{ def reads(jsValue: JsValue): JsResult[T] = { val className = classTag.runtimeClass.getSimpleName jsValue\"type" match { case x: JsDefined => x.value.validate[String].filter(_ == className).flatMap(_ => enclosed.reads(jsValue)) case other => JsError(s"tagWithType cannot deserialize json without a matching type field. Found: " + jsValue) } } def writes(value: T): JsValue = { val className = classTag.runtimeClass.getSimpleName enclosed.writes(value) match{ case x: JsObject => x ++ JsObject(Map("type" -> JsString(className))) case other => throw new Exception(s"Cannot use tagWithType on Format[$className], because writes didn't return a JsObject but: " + other + " for " + value) } } } }
@alkersan @cvogt this is like Variant types from https://github.com/aparo/play-json-extra
generalize: