All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.http.decoder.Validator Maven / Gradle / Ivy

package io.datakernel.http.decoder;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

import static io.datakernel.common.collection.CollectionUtils.concat;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;

/**
 * An enhanced predicate which can return a list of errors for given input object.
 * This can be used to put additional constraints on the parsed object from HTTP decoder.
 * For example to ensure, that age of the person is in range 0-100 or something
 * and return a specific error tree for that input.
 */
public interface Validator {
	List validate(T value);

	/**
	 * Combines this validator with some other one.
	 * This calls both the validators on the same input
	 * and then returns their errors combined.
	 */
	default Validator and(Validator next) {
		if (this == alwaysOk()) return next;
		if (next == alwaysOk()) return this;
		return value -> {
			List thisErrors = this.validate(value);
			List nextErrors = next.validate(value);
			return concat(thisErrors, nextErrors);
		};
	}

	/**
	 * Combines this validator with some other one.
	 * This calls the validators in order and if the first fails
	 * the the second is never called and errors of the first one are returned.
	 */
	default Validator then(Validator next) {
		if (this == alwaysOk()) return next;
		if (next == alwaysOk()) return this;
		return value -> {
			List thisErrors = this.validate(value);
			return thisErrors.isEmpty() ? next.validate(value) : thisErrors;
		};
	}

	static  Validator alwaysOk() {
		return value -> emptyList();
	}

	/**
	 * Combines multiple validators repeatedly with the {@link #then} call.
	 */
	@SafeVarargs
	static  Validator sequence(Validator... validators) {
		return sequence(Arrays.asList(validators));
	}

	/**
	 * Combines multiple validators repeatedly with the {@link #then} call.
	 */

	static  Validator sequence(List> validators) {
		return validators.stream().reduce(alwaysOk(), Validator::then);
	}

	/**
	 * Combines multiple validators repeatedly with the {@link #and} call.
	 */
	@SafeVarargs
	static  Validator of(Validator... validators) {
		return of(Arrays.asList(validators));
	}

	/**
	 * Combines multiple validators repeatedly with the {@link #and} call.
	 */
	static  Validator of(List> validators) {
		return validators.stream().reduce(alwaysOk(), Validator::and);
	}

	/**
	 * Creates the validator from the given predicate, using template
	 * as a message, formatted with the unsatisfactory value as a first argument.
	 */
	static  Validator of(Predicate predicate, String template) {
		return value -> predicate.test(value) ?
				emptyList() :
				singletonList(DecodeError.of(template, value));
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy