in elitzur-core/src/main/scala/com/spotify/elitzur/validators/Validator.scala [327:401]
def validationLoop[T](
validatorAccessors: Array[ValidatorAccessor[Any]],
constructor: Seq[Any] => T,
outermostClassName: String,
path: String = "",
config: ValidationRecordConfig = DefaultRecordConfig
)(implicit reporter: MetricsReporter): PostValidation[T] = {
val cs = new Array[Any](validatorAccessors.length)
var i = 0
var atLeastOneValid = false
var atLeastOneInvalid = false
while (i < validatorAccessors.length) {
val accessor = validatorAccessors(i)
val v =
if (!accessor.validator.isInstanceOf[IgnoreValidator[_]]) {
val name = new JStringBuilder(path.length + accessor.label.length)
.append(path)
.append(accessor.label)
.toString
val o = if (accessor.validator.isInstanceOf[FieldValidator[_]]) {
val fieldConf = config.fieldConfig(name)
validateField(
accessor.validator.asInstanceOf[FieldValidator[Any]],
Unvalidated(accessor.value),
fieldConf,
outermostClassName,
name
)
} else {
// SeqLikeValidator can contain either nested records or fields we want to validate
// we don't want to append a delimiter to leaf-field's path so we wait and branch the
// logic within SeqLikeValidator
val nextPath =
if (accessor.validator.isInstanceOf[SeqLikeValidator[_, Seq]]) {
new JStringBuilder(path.length + accessor.label.length)
.append(path)
.append(accessor.label)
.toString
} else {
new JStringBuilder(path.length + accessor.label.length + 1)
.append(path)
.append(accessor.label)
.append(".")
.toString
}
accessor.validator.validateRecord(
Unvalidated(accessor.value),
nextPath,
Some(outermostClassName),
config
)
}
if (o.isValid) {
atLeastOneValid = true
} else if (o.isInvalid) {
atLeastOneInvalid = true
}
o.forceGet
} else {
accessor.value
}
cs.update(i, v)
i = i + 1
}
val record = constructor(ArraySeq.unsafeWrapArray(cs))
if (atLeastOneInvalid) {
Invalid(record)
} else if (atLeastOneValid) {
Valid(record)
} else {
IgnoreValidation(record)
}
}