@startuml abstract class Validator { + validate(name: string, val: mixed): array + then(other: Validator): Validator } class ComposedValidator extends Validator { - first: Validator - then: Validator + __construct(first: Validator, then: Validator) validate(name: string, val: mixed): array } class SimpleFunctionValidator extends Validator { - predicate: callable - error_factory: callable + __construct(predicate: callable, errorsFactory: callable) + validate(name: string, val: mixed): array } class ValidationFail implements JsonSerialize { - kind: string - message: string + __construct(kind: string, message: string) + getMessage(): string + getKind(): string + jsonSerialize() + notFound(message: string): ValidationFail } class FieldValidationFail extends ValidationFail { - fieldName: string + __construct(fieldName: string, message: string) + getFieldName(): string + jsonSerialize() + invalidChars(fieldName: string): FieldValidationFail + empty(fieldName: string): FieldValidationFail + missing(fieldName: string): FieldValidationFail } class Validation { + validate(val: mixed, valName: string, failures: &array, validators: Validator...): bool } class Validators { + nonEmpty(): Validator + shorterThan(limit: int): Validator + userString(maxLen: int): Validator } @enduml