Reputation: 179
I've got some json and I have to encrypt all the values. Below is a json, all the values of which should be updated:
json = Json.parse("""{ "key1" : 1.5, "key2" : [ {"key211": 1, "key212": "value212"}, {"key221": 2, "key222": "value222"} ] "key3" : { "key31" : true, "key32" : "value32" }, "key4" : 17 }"""
After encrypting and updating all the values, it should look like this:
val json = Json.parse("""{ "key1" : "uhKhbofQtL", "key2" : [ {"key211": "FxnbGGZFMW", "key212": "VsdfdGfg"}, {"key221": "sdffFdd", "key222": "Fsdfsfds"} ] "key3" : { "key31" : "Fsdfasdf", "key32" : "Vsdfsdfsdfs" }, "key4" : "sfsdfFSdfs" }"""
How can I do it?
Upvotes: 0
Views: 127
Reputation: 179
I've solved this problem and solution is below
implicit val readsMap: Reads[Map[String, Any]] = Reads[Map[String, Any]](m => Reads.mapReads[Any](metaValueReader).reads(m))
implicit val writesMap: Writes[Map[String, Any]] = Writes[Map[String, Any]](m => Writes.mapWrites[Any](metaValueWriter).writes(m))
def metaValueReader(jsValue: JsValue): JsResult[Any] = jsValue match {
case JsObject(m) => JsSuccess(m.map { case (k, v) => k -> metaValueReader(v) })
case JsArray(arr) => JsSuccess(arr.map(metaValueReader))
case JsBoolean(b) => JsSuccess(b).map(encryptValue)
case JsNumber(n) => JsSuccess(n).map(encryptValue)
case JsString(s) => JsSuccess(s).map(encryptValue)
case JsNull => JsSuccess("").map(encryptValue)
case badValue => JsError(s"$badValue is not a valid value")
}
def metaValueWriter(value: Any): JsValue = value match {
case jsRes: JsSuccess[Any] => metaValueWriter(jsRes.get)
case m: Map[String, Any] => JsObject(m.map { case (k, v) => k -> metaValueWriter(v) })
case arr: Seq[Any] => JsArray(arr.map(metaValueWriter))
case s: String => JsString(s)
}
How can I improve this code?
Upvotes: 0
Reputation: 40500
Parse it as a Map
, then traverse the map and encrypt:
def encrypt(data: Any, enc: Any => String): Any = data match {
case v: Map[String, Any] => v.map { case (k,v) => k -> encrypt(v, enc) }
case v: List[Any] => v.map(encrypt(_, enc))
case v => enc(v)
}
Upvotes: 3