Skip to content

Commit

Permalink
Merge pull request #29 from dnanexus/eval-multi
Browse files Browse the repository at this point in the history
fix evaluation of multi-type
  • Loading branch information
jdidion authored Jan 27, 2022
2 parents 4d61657 + e75f587 commit 088358d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* `Evaluator.finalizeInputValue` loads file contents from remote file source if file does not exist locally
* `CwlType.coerceTo` now returns both the coerced-to type and value
* Added `CwlType.CwlGenericRecord`, which is coercible to either `CwlInputRecord` or `CwlOutputRecord`
* Fixes evaluation of values with multiple possible types

## 0.7.4 (2021-01-05)

Expand Down
51 changes: 30 additions & 21 deletions src/main/scala/dx/cwl/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -966,28 +966,37 @@ case class Evaluator(jsEnabled: Boolean = false,
.to(TreeSeqMap)
(CwlOutputRecord(fields), value)
case (CwlMulti(types), _) =>
types.iterator
.map {
case CwlAny => None
case t =>
try {
Some(inner(innerValue, t))
} catch {
case _: Throwable => None
}
}
.collectFirst {
case Some(value) => value
}
.getOrElse(
if (types.contains(CwlAny)) {
(CwlAny, innerValue)
} else {
throw new Exception(
s"${innerValue} does not evaluate to any of ${types}"
)
types.flatMap {
case CwlAny => None
case t =>
try {
Some(inner(innerValue, t))
} catch {
case _: Throwable => None
}
} match {
case Vector(result) => result
case Vector() if types.contains(CwlAny) => (CwlAny, innerValue)
case Vector() =>
throw new Exception(
s"${innerValue} does not evaluate to any of ${types}"
)
case v =>
// we have multiple evaluation results - for the type, create a CwlMulti from all the types, and for
// the value, if there are multiple we first prefer string (because it is coercible to the most other
// types and then just pick the first one
val (types, values) = v.unzip
val distinctValues = values.toSet
val value = Option
.when(distinctValues.size > 1) {
distinctValues.collectFirst {
case s: StringValue => s
}
}
)
.flatten
.getOrElse(distinctValues.head)
(CwlType.flatten(types), value)
}
case _ => checkCoercibleTo(innerValue, innerType)
}
}
Expand Down

0 comments on commit 088358d

Please sign in to comment.