aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibility.scala
blob: 925ba65660a5a1bc9a3ebc6411c2fca0dc03c07a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package xyz.driver.pdsuidomain.formats.json

import spray.json.DefaultJsonProtocol._
import spray.json._
import DefaultJsonProtocol._
import xyz.driver.core.Id
import xyz.driver.core.json._
import xyz.driver.entities.labels.LabelValue
import xyz.driver.pdsuidomain.entities.eligibility._

object eligibility {
  import export._
  import xyz.driver.formats.json.assay._
  import xyz.driver.formats.json.common._
  import xyz.driver.formats.json.labels._
  import xyz.driver.formats.json.process._
  import xyz.driver.pdsuidomain.formats.json.document._
  import xyz.driver.pdsuidomain.formats.json.record._
  import xyz.driver.pdsuidomain.formats.json.export._

  implicit val molecularDocumentFormat: RootJsonFormat[MolecularEvidenceDocument] = jsonFormat7(
    MolecularEvidenceDocument)
  implicit val clinicalDocumentFormat: RootJsonFormat[ClinicalEvidenceDocument] = jsonFormat7(ClinicalEvidenceDocument)

  implicit val evidenceDocumentFormat: RootJsonFormat[EvidenceDocument] =
    GadtJsonFormat.create[EvidenceDocument]("evidenceDocumentType") {
      case _: MolecularEvidenceDocument => "Molecular"
      case _: ClinicalEvidenceDocument  => "Clinical"
    } {
      case "Molecular" => molecularDocumentFormat
      case "Clinical"  => clinicalDocumentFormat
    }

  implicit object evidenceFormat extends RootJsonFormat[Evidence] {

    override def write(evidence: Evidence): JsValue = {
      JsObject(
        "evidenceId"     -> evidence.evidenceId.toJson,
        "evidenceText"   -> evidence.evidenceText.toJson,
        "labelValue"     -> evidence.labelValue.toJson,
        "document"       -> evidence.document.toJson,
        "isPrimaryValue" -> evidence.isPrimaryValue.toJson
      )
    }

    override def read(json: JsValue): Evidence = {
      json match {
        case JsObject(fields) =>
          val evidenceId = fields
            .get("evidenceId")
            .map(_.convertTo[Id[Evidence]])

          val evidenceText = fields
            .get("evidenceText")
            .map(_.convertTo[String])
            .getOrElse(deserializationError(s"Evidence json object do not contain 'evidenceText' field: $json"))

          val labelValue = fields
            .get("labelValue")
            .map(_.convertTo[LabelValue])
            .getOrElse(deserializationError(s"Evidence json object do not contain 'labelValue' field: $json"))

          val isDriverDocument = fields
            .get("document")
            .flatMap {
              case JsObject(fieldMap) =>
                fieldMap
                  .get("isDriverDocument")
                  .map(_.convertTo[Boolean])
              case _ => deserializationError(s"Expected Json Object as 'isDriverDocument', but got $json")
            }
            .getOrElse(deserializationError(s"Evidence json object do not contain 'document' field: $json"))

          val document = customDocumentParser(isDriverDocument, fields, json)

          val isPrimaryValue = fields
            .get("isPrimaryValue")
            .map(_.convertTo[Option[Boolean]])
            .getOrElse(deserializationError(s"Evidence json object do not contain 'isPrimaryValue' field: $json"))

          Evidence(evidenceId, evidenceText, labelValue, document, isPrimaryValue)
        case _ => deserializationError(s"Expected Json Object as 'Evidence', but got $json")
      }
    }

    def customDocumentParser(isDriverDocument: Boolean,
                             fields: Map[String, JsValue],
                             json: JsValue): EvidenceDocument = {
      fields.get("document").fold { deserializationError(s"Expected Json Object as 'Document', but got $json") } {
        document =>
          if (isDriverDocument) document.convertTo[MolecularEvidenceDocument]
          else document.convertTo[ClinicalEvidenceDocument]
      }
    }
  }

  implicit def labelWithEvidenceJsonFormat: RootJsonFormat[LabelEvidence] = jsonFormat2(LabelEvidence)

  implicit def labelRankingFormat: RootJsonFormat[LabelMismatchRank]     = jsonFormat4(LabelMismatchRank)
  implicit def labelRankingsFormat: RootJsonFormat[MismatchRankedLabels] = jsonFormat2(MismatchRankedLabels)

  implicit def matchedPatientFormat: RootJsonFormat[MatchedPatient] = jsonFormat6(MatchedPatient)

  implicit lazy val eligibleTrialFormat: RootJsonFormat[EligibleTrial] = jsonFormat2(EligibleTrial.apply)
  implicit lazy val eligibleArmFormat: RootJsonFormat[EligibleArm] = jsonFormat2(EligibleArm.apply)
  implicit lazy val eligibleCriterionFormat: RootJsonFormat[EligibleCriterion] = jsonFormat2(EligibleCriterion.apply)

}