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.verifyOperation; 024import static java.util.Objects.requireNonNull; 025 026import java.util.concurrent.CompletionStage; 027import java.util.function.DoubleConsumer; 028import java.util.function.DoubleFunction; 029import java.util.function.Function; 030import java.util.function.Supplier; 031 032/** 033 * Represents an operation that accepts a single {@code double}-valued argument, 034 * may throw exception and returns no result. This is the primitive type 035 * specialization of {@link ConsumerWithException} for {@code double}. Unlike 036 * most other functional interfaces, {@code DoubleConsumerWithException} is 037 * expected to operate via side-effects. 038 * <h3>General contract</h3> 039 * <ul> 040 * <li><b>{@link #accept(double) void accept(double value) throws 041 * E}</b> - The functional method.</li> 042 * <li><b>uncheck</b> - Return a {@code DoubleConsumer}</li> 043 * <li><b>lift</b> - Return a {@code DoubleConsumer}</li> 044 * <li><b>ignore</b> - Return a {@code DoubleConsumer}</li> 045 * </ul> 046 * 047 * @see DoubleConsumer 048 * @param <E> 049 * the type of the potential exception of the operation 050 */ 051@FunctionalInterface 052public interface DoubleConsumerWithException<E extends Exception> extends 053 NoReturnExceptionHandlerSupport<DoubleConsumer, DoubleFunction<CompletionStage<Void>>, DoubleConsumerWithException<E>> { 054 055 /** 056 * Performs this operation on the given argument. 057 * 058 * @param value 059 * the input argument 060 * @throws E 061 * any exception 062 * @see DoubleConsumer#accept(double) 063 */ 064 void accept(double value) throws E; 065 066 /** 067 * Converts this {@code DoubleConsumerWithException} to a {@code DoubleConsumer} 068 * that wraps exception to {@code RuntimeException}. 069 * 070 * @return the unchecked operation 071 * @see #unchecked(DoubleConsumerWithException) 072 * @see #unchecked(DoubleConsumerWithException, Function) 073 */ 074 @Override 075 default DoubleConsumer uncheck() { 076 return t -> NoReturnExceptionHandlerSupport.unchecked(() -> accept(t), throwingHandler()); 077 } 078 079 /** 080 * Converts this {@code DoubleConsumerWithException} to a <i>lifted</i> 081 * {@code DoubleConsumer} ignoring exception. 082 * 083 * @return the operation that ignore error 084 * @see #ignored(DoubleConsumerWithException) 085 */ 086 @Override 087 default DoubleConsumer ignore() { 088 return t -> NoReturnExceptionHandlerSupport.unchecked(() -> accept(t), notThrowingHandler()); 089 } 090 091 /** 092 * Converts this {@code DoubleConsumerWithException} to a <i>staged</i> 093 * {@code DoubleFunction} that return a {@code CompletionStage}. 094 * 095 * @return the staged operation. 096 * @since 1.1.0 097 */ 098 @Override 099 default DoubleFunction<CompletionStage<Void>> stage() { 100 return t -> NoReturnExceptionHandlerSupport.staged(() -> accept(t)); 101 } 102 103 /** 104 * Returns a composed {@code DoubleConsumerWithException} that performs, in 105 * sequence, this operation followed by the {@code after} operation. If 106 * performing either operation throws an exception, it is relayed to the caller 107 * of the composed operation. If performing this operation throws an exception, 108 * the {@code after} operation will not be performed. 109 * 110 * @param after 111 * the operation to perform after this operation 112 * @return a composed {@code DoubleConsumer} that performs in sequence this 113 * operation followed by the {@code after} operation 114 * @throws NullPointerException 115 * if {@code after} is null 116 * 117 * @see DoubleConsumer#andThen(DoubleConsumer) 118 */ 119 default DoubleConsumerWithException<E> andThen(DoubleConsumerWithException<? extends E> after) { 120 requireNonNull(after); 121 return t -> { 122 accept(t); 123 after.accept(t); 124 }; 125 } 126 127 /** 128 * Returns an operation 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 an operation that always throw exception 135 */ 136 static <E extends Exception> DoubleConsumerWithException<E> failing(Supplier<E> exceptionBuilder) { 137 return t -> { 138 throw exceptionBuilder.get(); 139 }; 140 } 141 142 /** 143 * Converts a {@code DoubleConsumerWithException} to a {@code DoubleConsumer} 144 * that wraps exception to {@code RuntimeException}. 145 * 146 * @param operation 147 * to be unchecked 148 * @param <E> 149 * the type of the potential exception 150 * @return the unchecked operation 151 * @see #uncheck() 152 * @see #unchecked(DoubleConsumerWithException, Function) 153 * @throws NullPointerException 154 * if operation is null 155 */ 156 static <E extends Exception> DoubleConsumer unchecked(DoubleConsumerWithException<E> operation) { 157 return verifyOperation(operation).uncheck(); 158 } 159 160 /** 161 * Converts a {@code DoubleConsumerWithException} to a {@code DoubleConsumer} 162 * that wraps exception to {@code RuntimeException} by using the provided 163 * mapping function. 164 * 165 * @param operation 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 operation 172 * @see #uncheck() 173 * @see #unchecked(DoubleConsumerWithException) 174 * @throws NullPointerException 175 * if operation or exceptionMapper is null 176 */ 177 static <E extends Exception> DoubleConsumer unchecked(DoubleConsumerWithException<E> operation, 178 Function<Exception, RuntimeException> exceptionMapper) { 179 verifyOperation(operation); 180 verifyExceptionMapper(exceptionMapper); 181 return new DoubleConsumerWithException<E>() { 182 183 @Override 184 public void accept(double value) throws E { 185 operation.accept(value); 186 } 187 188 @Override 189 public Function<Exception, RuntimeException> exceptionMapper() { 190 return exceptionMapper; 191 } 192 193 }.uncheck(); 194 } 195 196 /** 197 * Converts a {@code DoubleConsumerWithException} to a lifted 198 * {@code DoubleConsumer} ignoring exception. 199 * 200 * @param operation 201 * to be lifted 202 * @param <E> 203 * the type of the potential exception 204 * @return the lifted operation 205 * @see #lift() 206 * @throws NullPointerException 207 * if operation is null 208 */ 209 static <E extends Exception> DoubleConsumer lifted(DoubleConsumerWithException<E> operation) { 210 return verifyOperation(operation).lift(); 211 } 212 213 /** 214 * Converts a {@code DoubleConsumerWithException} to a lifted 215 * {@code DoubleConsumer} ignoring exception. 216 * 217 * @param operation 218 * to be lifted 219 * @param <E> 220 * the type of the potential exception 221 * @return the lifted operation 222 * @see #ignore() 223 * @throws NullPointerException 224 * if operation is null 225 */ 226 static <E extends Exception> DoubleConsumer ignored(DoubleConsumerWithException<E> operation) { 227 return verifyOperation(operation).ignore(); 228 } 229 230 /** 231 * Converts a {@code DoubleConsumerWithException} to a staged 232 * {@code DoubleFunction}. 233 * 234 * @param operation 235 * to be staged 236 * @param <E> 237 * the type of the potential exception 238 * @return the staged operation 239 * @throws NullPointerException 240 * if operation is null 241 * @since 1.1.0 242 */ 243 static <E extends Exception> DoubleFunction<CompletionStage<Void>> staged( 244 DoubleConsumerWithException<E> operation) { 245 return verifyOperation(operation).stage(); 246 } 247 248 /** 249 * Converts a {@code DoubleConsumerWithException} to a 250 * {@code ConsumerWithException}. 251 * 252 * @param operation 253 * to be converted 254 * @param <E> 255 * the type of the potential exception 256 * @return the consumer 257 * @throws NullPointerException 258 * if operation is null 259 */ 260 static <E extends Exception> ConsumerWithException<Double, E> asConsumer(DoubleConsumerWithException<E> operation) { 261 return verifyOperation(operation)::accept; 262 } 263 264}