001/**
002 * Powerunit - A JDK1.8 test framework
003 * Copyright (C) 2014 Mathieu Boretti.
004 *
005 * This file is part of Powerunit
006 *
007 * Powerunit is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation, either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * Powerunit is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
019 */
020package ch.powerunit.extensions.exceptions;
021
022import static ch.powerunit.extensions.exceptions.Constants.verifyExceptionMapper;
023import static ch.powerunit.extensions.exceptions.Constants.verifyFunction;
024
025import java.util.function.DoubleToIntFunction;
026import java.util.function.Function;
027import java.util.function.Supplier;
028
029/**
030 * Represents a function that accepts a double-valued argument, may throw
031 * exception and produces an int-valued result. This is the
032 * {@code double}-to-{@code int} primitive specialization for
033 * {@link FunctionWithException}.
034 * <h3>General contract</h3>
035 * <ul>
036 * <li><b>{@link #applyAsInt(double) int applyAsInt(double value) throws
037 * E}</b>&nbsp;-&nbsp;The functional method.</li>
038 * <li><b>uncheck</b>&nbsp;-&nbsp;Return a {@code DoubleToIntFunction}</li>
039 * <li><b>lift</b>&nbsp;-&nbsp;Return a {@code DoubleToIntFunction}</li>
040 * <li><b>ignore</b>&nbsp;-&nbsp;Return a {@code DoubleToIntFunction}</li>
041 * </ul>
042 *
043 * @see DoubleToIntFunction
044 * @param <E>
045 *            the type of the potential exception of the function
046 */
047@FunctionalInterface
048public interface DoubleToIntFunctionWithException<E extends Exception>
049                extends PrimitiveReturnExceptionHandlerSupport<DoubleToIntFunction, DoubleToIntFunctionWithException<E>>,
050                IntDefaultValue {
051
052        /**
053         * Applies this function to the given argument.
054         *
055         * @param value
056         *            the function argument
057         * @return the function result
058         * @throws E
059         *             any exception
060         * @see DoubleToIntFunction#applyAsInt(double)
061         */
062        int applyAsInt(double value) throws E;
063
064        @Override
065        default DoubleToIntFunction uncheckOrIgnore(boolean uncheck) {
066                return value -> {
067                        try {
068                                return applyAsInt(value);
069                        } catch (Exception e) {
070                                PrimitiveReturnExceptionHandlerSupport.handleException(uncheck, e, exceptionMapper());
071                                return defaultValue();
072                        }
073                };
074        }
075
076        /**
077         * Returns a function that always throw exception.
078         *
079         * @param exceptionBuilder
080         *            the supplier to create the exception
081         * @param <E>
082         *            the type of the exception
083         * @return a function that always throw exception
084         */
085        static <E extends Exception> DoubleToIntFunctionWithException<E> failing(Supplier<E> exceptionBuilder) {
086                return t -> {
087                        throw exceptionBuilder.get();
088                };
089        }
090
091        /**
092         * Converts a {@code DoubleToIntFunctionWithException} to a
093         * {@code DoubleToIntFunction} that wraps exception to {@code RuntimeException}.
094         *
095         * @param function
096         *            to be unchecked
097         * @param <E>
098         *            the type of the potential exception
099         * @return the unchecked function
100         * @see #uncheck()
101         * @see #unchecked(DoubleToIntFunctionWithException, Function)
102         * @throws NullPointerException
103         *             if function is null
104         */
105        static <E extends Exception> DoubleToIntFunction unchecked(DoubleToIntFunctionWithException<E> function) {
106                return verifyFunction(function).uncheck();
107        }
108
109        /**
110         * Converts a {@code DoubleToIntFunctionWithException} to a
111         * {@code DoubleToIntFunction} that wraps exception to {@code RuntimeException}
112         * by using the provided mapping function.
113         *
114         * @param function
115         *            the be unchecked
116         * @param exceptionMapper
117         *            a function to convert the exception to the runtime exception.
118         * @param <E>
119         *            the type of the potential exception
120         * @return the unchecked exception
121         * @see #uncheck()
122         * @see #unchecked(DoubleToIntFunctionWithException)
123         * @throws NullPointerException
124         *             if function or exceptionMapper is null
125         */
126        static <E extends Exception> DoubleToIntFunction unchecked(DoubleToIntFunctionWithException<E> function,
127                        Function<Exception, RuntimeException> exceptionMapper) {
128                verifyFunction(function);
129                verifyExceptionMapper(exceptionMapper);
130                return new DoubleToIntFunctionWithException<E>() {
131
132                        @Override
133                        public int applyAsInt(double value) throws E {
134                                return function.applyAsInt(value);
135                        }
136
137                        @Override
138                        public Function<Exception, RuntimeException> exceptionMapper() {
139                                return exceptionMapper;
140                        }
141
142                }.uncheck();
143        }
144
145        /**
146         * Converts a {@code DoubleToIntFunctionWithException} to a lifted
147         * {@code DoubleToIntFunction} returning {@code 0} in case of exception.
148         *
149         * @param function
150         *            to be lifted
151         * @param <E>
152         *            the type of the potential exception
153         * @return the lifted function
154         * @see #lift()
155         * @throws NullPointerException
156         *             if function is null
157         */
158        static <E extends Exception> DoubleToIntFunction lifted(DoubleToIntFunctionWithException<E> function) {
159                return verifyFunction(function).lift();
160        }
161
162        /**
163         * Converts a {@code DoubleToIntFunctionWithException} to a lifted
164         * {@code DoubleToIntFunction} returning {@code 0} in case of exception.
165         *
166         * @param function
167         *            to be lifted
168         * @param <E>
169         *            the type of the potential exception
170         * @return the lifted function
171         * @see #ignore()
172         * @throws NullPointerException
173         *             if function is null
174         */
175        static <E extends Exception> DoubleToIntFunction ignored(DoubleToIntFunctionWithException<E> function) {
176                return verifyFunction(function).ignore();
177        }
178
179        /**
180         * Converts a {@code DoubleToIntFunctionWithException} to a lifted
181         * {@code DoubleToIntFunction} returning a default value in case of exception.
182         *
183         * @param function
184         *            to be lifted
185         * @param defaultValue
186         *            value in case of exception
187         * @param <E>
188         *            the type of the potential exception
189         * @return the lifted function
190         * @see #ignore()
191         * @see #ignored(DoubleToIntFunctionWithException)
192         * @throws NullPointerException
193         *             if function is null
194         * @since 3.0.0
195         */
196        static <E extends Exception> DoubleToIntFunction ignored(DoubleToIntFunctionWithException<E> function,
197                        int defaultValue) {
198                verifyFunction(function);
199                return new DoubleToIntFunctionWithException<E>() {
200
201                        @Override
202                        public int applyAsInt(double value) throws E {
203                                return function.applyAsInt(value);
204                        }
205
206                        @Override
207                        public int defaultValue() {
208                                return defaultValue;
209                        }
210
211                }.ignore();
212        }
213
214}