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; 024import static java.util.Objects.requireNonNull; 025 026import java.util.function.Function; 027import java.util.function.IntUnaryOperator; 028import java.util.function.Supplier; 029 030/** 031 * Represents an operation on a single {@code int}-valued operand that produces 032 * an {@code int}-valued result and may throws exception. This is the primitive 033 * type specialization of {@link UnaryOperatorWithException} for {@code int}. 034 * <h3>General contract</h3> 035 * <ul> 036 * <li><b>{@link #applyAsInt(int) int applyAsInt(int operand) throws 037 * E}</b> - The functional method.</li> 038 * <li><b>uncheck</b> - Return a {@code IntUnaryOperator}</li> 039 * <li><b>lift</b> - Return a {@code IntUnaryOperator}</li> 040 * <li><b>ignore</b> - Return a {@code IntUnaryOperator}</li> 041 * </ul> 042 * 043 * @see IntUnaryOperator 044 * @param <E> 045 * the type of the potential exception of the function 046 */ 047@FunctionalInterface 048public interface IntUnaryOperatorWithException<E extends Exception> extends 049 PrimitiveReturnExceptionHandlerSupport<IntUnaryOperator, IntUnaryOperatorWithException<E>>, IntDefaultValue { 050 051 /** 052 * Applies this operator to the given operand. 053 * 054 * @param operand 055 * the operand 056 * @return the operator result 057 * @throws E 058 * any exception 059 * @see IntUnaryOperator#applyAsInt(int) 060 */ 061 int applyAsInt(int operand) throws E; 062 063 @Override 064 default IntUnaryOperator uncheckOrIgnore(boolean uncheck) { 065 return t -> { 066 try { 067 return applyAsInt(t); 068 } catch (Exception e) { 069 PrimitiveReturnExceptionHandlerSupport.handleException(uncheck, e, exceptionMapper()); 070 return defaultValue(); 071 } 072 }; 073 } 074 075 /** 076 * Returns a composed operator that first applies the {@code before} operator to 077 * its input, and then applies this operator to the result. If evaluation of 078 * either operator throws an exception, it is relayed to the caller of the 079 * composed operator. 080 * 081 * @param before 082 * the operator to apply before this operator is applied 083 * @return a composed operator that first applies the {@code before} operator 084 * and then applies this operator 085 * @throws NullPointerException 086 * if before is null 087 * 088 * @see #andThen(IntUnaryOperatorWithException) 089 */ 090 default IntUnaryOperatorWithException<E> compose(IntUnaryOperatorWithException<? extends E> before) { 091 requireNonNull(before); 092 return v -> applyAsInt(before.applyAsInt(v)); 093 } 094 095 /** 096 * Returns a composed operator that first applies this operator to its input, 097 * and then applies the {@code after} operator to the result. If evaluation of 098 * either operator throws an exception, it is relayed to the caller of the 099 * composed operator. 100 * 101 * @param after 102 * the operator to apply after this operator is applied 103 * @return a composed operator that first applies this operator and then applies 104 * the {@code after} operator 105 * @throws NullPointerException 106 * if after is null 107 * 108 * @see #compose(IntUnaryOperatorWithException) 109 */ 110 default IntUnaryOperatorWithException<E> andThen(IntUnaryOperatorWithException<? extends E> after) { 111 requireNonNull(after); 112 return t -> after.applyAsInt(applyAsInt(t)); 113 } 114 115 /** 116 * Returns a unary operator that always returns its input argument. 117 * 118 * @return a unary operator that always returns its input argument 119 * 120 * @param <E> 121 * the exception that may be thrown 122 */ 123 static <E extends Exception> IntUnaryOperatorWithException<E> identity() { 124 return t -> t; 125 } 126 127 /** 128 * Returns a function that always throw exception. 129 * 130 * @param exceptionBuilder 131 * the supplier to create the exception 132 * @param <E> 133 * the type of the exception 134 * @return a function that always throw exception 135 */ 136 static <E extends Exception> IntUnaryOperatorWithException<E> failing(Supplier<E> exceptionBuilder) { 137 return t -> { 138 throw exceptionBuilder.get(); 139 }; 140 } 141 142 /** 143 * Converts a {@code IntUnaryOperatorException} to a {@code IntUnaryOperator} 144 * that wraps exception to {@code RuntimeException}. 145 * 146 * @param function 147 * to be unchecked 148 * @param <E> 149 * the type of the potential exception 150 * @return the unchecked function 151 * @see #uncheck() 152 * @see #unchecked(IntUnaryOperatorWithException, Function) 153 * @throws NullPointerException 154 * if function is null 155 */ 156 static <E extends Exception> IntUnaryOperator unchecked(IntUnaryOperatorWithException<E> function) { 157 return verifyFunction(function).uncheck(); 158 } 159 160 /** 161 * Converts a {@code IntUnaryOperatorWithException} to a 162 * {@code IntUnaryOperator} that wraps exception to {@code RuntimeException} by 163 * using the provided mapping function. 164 * 165 * @param function 166 * the be unchecked 167 * @param exceptionMapper 168 * a function to convert the exception to the runtime exception. 169 * @param <E> 170 * the type of the potential exception 171 * @return the unchecked function 172 * @see #uncheck() 173 * @see #unchecked(IntUnaryOperatorWithException) 174 * @throws NullPointerException 175 * if function or exceptionMapper is null 176 */ 177 static <E extends Exception> IntUnaryOperator unchecked(IntUnaryOperatorWithException<E> function, 178 Function<Exception, RuntimeException> exceptionMapper) { 179 verifyFunction(function); 180 verifyExceptionMapper(exceptionMapper); 181 return new IntUnaryOperatorWithException<E>() { 182 183 @Override 184 public int applyAsInt(int operand) throws E { 185 return function.applyAsInt(operand); 186 } 187 188 @Override 189 public Function<Exception, RuntimeException> exceptionMapper() { 190 return exceptionMapper; 191 } 192 193 }.uncheck(); 194 } 195 196 /** 197 * Converts a {@code IntUnaryOperatorWithException} to a lifted 198 * {@code IntUnaryOperator} using {@code 0} as return value in case of error. 199 * 200 * @param function 201 * to be lifted 202 * @param <E> 203 * the type of the potential exception 204 * @return the lifted function 205 * @see #lift() 206 * @throws NullPointerException 207 * if function is null 208 */ 209 static <E extends Exception> IntUnaryOperator lifted(IntUnaryOperatorWithException<E> function) { 210 return verifyFunction(function).lift(); 211 } 212 213 /** 214 * Converts a {@code IntUnaryOperatorWithException} to a lifted 215 * {@code IntUnaryOperator} returning {@code 0} in case of exception. 216 * 217 * @param function 218 * to be lifted 219 * @param <E> 220 * the type of the potential exception 221 * @return the lifted function 222 * @see #ignore() 223 * @throws NullPointerException 224 * if function is null 225 */ 226 static <E extends Exception> IntUnaryOperator ignored(IntUnaryOperatorWithException<E> function) { 227 return verifyFunction(function).ignore(); 228 } 229 230 /** 231 * Converts a {@code IntUnaryOperatorWithException} to a lifted 232 * {@code IntUnaryOperator} returning a default value in case of exception. 233 * 234 * @param function 235 * to be lifted 236 * @param defaultValue 237 * value in case of exception 238 * @param <E> 239 * the type of the potential exception 240 * @return the lifted function 241 * @see #ignore() 242 * @see #ignored(IntUnaryOperatorWithException) 243 * @throws NullPointerException 244 * if function is null 245 * @since 3.0.0 246 */ 247 static <E extends Exception> IntUnaryOperator ignored(IntUnaryOperatorWithException<E> function, int defaultValue) { 248 verifyFunction(function); 249 return new IntUnaryOperatorWithException<E>() { 250 251 @Override 252 public int applyAsInt(int operand) throws E { 253 return function.applyAsInt(operand); 254 } 255 256 @Override 257 public int defaultValue() { 258 return defaultValue; 259 } 260 261 }.ignore(); 262 } 263 264}