/* * Copyright 2015 Mark Michaelis * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.mmichaelis.hamcrest.nextdeed.glue; import static java.util.Objects.requireNonNull; import com.google.common.base.Function; import org.jetbrains.annotations.NotNull; /** * <p> * A function which can be described. * </p> * <dl> * <dt><strong>Usage:</strong></dt> * <dd> * <pre>{@code * DescribedFunction.describe(fn).as("description"); * }</pre> * </dd> * </dl> * * @param <T> input type of function * @param <R> output type of function * @since 1.0.0 */ public class DescribedFunction<T, R> implements Function<T, R> { /** * The function to describe. * * @since 1.0.0 */ @NotNull private final Function<T, R> delegateFunction; /** * The description of the function. * * @since 1.0.0 */ @NotNull private final String description; /** * Constructor for the described function. * * @param delegateFunction function to describe (and to forward any requests to) * @param description description to use * @see #describe(Function) * @since 1.0.0 */ protected DescribedFunction(@NotNull Function<T, R> delegateFunction, @NotNull String description) { this.delegateFunction = requireNonNull(delegateFunction, "delegateFunction must not be null."); this.description = requireNonNull(description, "description must not be null."); } /** * Build described function. * * @param delegateFunction function to describe * @param <T> input type of function * @param <R> output type of function * @return builder for described function * @since 1.0.0 */ @NotNull public static <T, R> Builder<T, R> describe(@NotNull final Function<T, R> delegateFunction) { requireNonNull(delegateFunction, "delegateFunction must not be null."); return new Builder<T, R>() { @NotNull @Override public Function<T, R> as(@NotNull String description) { return new DescribedFunction<>(delegateFunction, description); } }; } /** * {@inheritDoc} * <p> * Redirects any calls to the delegate function. * </p> * * @since 1.0.0 */ @Override public R apply(T input) { return delegateFunction.apply(input); } /** * Actually provides the description for the delegate function. * * @return description * @since 1.0.0 */ @Override public String toString() { return description; } /** * Fluent builder interface for creating described functions. * * @param <T> input type of described function * @param <R> output type of described function * @since 1.0.0 */ public interface Builder<T, R> { /** * Define the description to use. * * @param description description for the function * @return describing function wrapper * @since 1.0.0 */ @NotNull Function<T, R> as(@NotNull String description); } }