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

org.rapidpm.frp.model.Result Maven / Gradle / Ivy

There is a newer version: 01.00.07-RPM
Show newest version
/**
 * Copyright © 2017 Sven Ruppert ([email protected])
 *
 * 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 org.rapidpm.frp.model;

import org.rapidpm.frp.functions.CheckedFunction;

import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Copyright (C) 2017 RapidPM - Sven Ruppert
 * 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.
 * 

* Created by Sven Ruppert - RapidPM - Team on 16.03.17. */ public interface Result { void ifPresentOrElse(Consumer action, Runnable emptyAction); void ifPresentOrElse(Consumer success, Consumer failure); void ifPresentOrElseAsync(Consumer action, Runnable emptyAction); void ifPresentOrElseAsync(Consumer success, Consumer failure); static Result failure(String errorMessage) { Objects.requireNonNull(errorMessage); return new Result.Failure<>(errorMessage); } static Result success(T value) { return new Result.Success<>(value); } static Result ofNullable(T value) { return ofNullable(value, "Object was null"); } static Result ofNullable(T value, String failedMessage) { return (Objects.nonNull(value)) ? success(value) : failure(failedMessage); } T get(); T getOrElse(Supplier supplier); Boolean isPresent(); Boolean isAbsent(); Result ifPresent(Consumer consumer); Result ifAbsent(Runnable action); Result ifFailed(Consumer failed); default Stream stream() { if (!isPresent()) { return Stream.empty(); } else { return Stream.of(get()); } } default Result or(Supplier> supplier) { Objects.requireNonNull(supplier); if (isPresent()) { return this; } else { @SuppressWarnings("unchecked") Result r = (Result) supplier.get(); return Objects.requireNonNull(r); } } default Optional toOptional() { return Optional.ofNullable(get()); } static Result fromOptional(Optional optional) { Objects.requireNonNull(optional); return optional .map(Result::success) .orElseGet(() -> failure("Optional hold a null value")); } default Result thenCombine(V value, BiFunction> func) { return func.apply(get(), value); } default CompletableFuture> thenCombineAsync(V value, BiFunction> func) { return CompletableFuture.supplyAsync(() -> func.apply(get(), value)); } default Result map(Function mapper) { Objects.requireNonNull(mapper); return isPresent() ? ((CheckedFunction) mapper::apply).apply(get()) : this.asFailure(); } default Result flatMap(Function> mapper) { Objects.requireNonNull(mapper); return this.isPresent() ? mapper.apply(get()) : this.asFailure(); } default Result asFailure() { return (isAbsent()) ? ofNullable(null) : failure("converted to Failure orig was " + this); } abstract class AbstractResult implements Result { protected final T value; public AbstractResult(T value) { this.value = value; } @Override public Result ifPresent(Consumer consumer) { Objects.requireNonNull(consumer); if (value != null) consumer.accept(value); return (this instanceof Failure) ? this : ofNullable(value); } @Override public Result ifAbsent(Runnable action) { Objects.requireNonNull(action); if (value == null) action.run(); return (this instanceof Failure) ? this : ofNullable(value); } public Boolean isPresent() { return (value != null) ? Boolean.TRUE : Boolean.FALSE; } public Boolean isAbsent() { return (value == null) ? Boolean.TRUE : Boolean.FALSE; } @Override public T get() { return Objects.requireNonNull(value); } @Override public T getOrElse(Supplier supplier) { Objects.requireNonNull(supplier); return (value != null) ? value : Objects.requireNonNull(supplier.get()); } } class Success extends AbstractResult { public Success(T value) { super(value); } @Override public void ifPresentOrElse(Consumer action, Runnable emptyAction) { action.accept(value); } @Override public void ifPresentOrElse(final Consumer success, final Consumer failure) { // TODO check if usefull -> Objects.requireNonNull(value); success.accept(value); } @Override public void ifPresentOrElseAsync(Consumer action, Runnable emptyAction) { CompletableFuture.runAsync(() -> action.accept(value)); } @Override public void ifPresentOrElseAsync(Consumer success, Consumer failure) { CompletableFuture.runAsync(() -> success.accept(value)); } public Result ifFailed(Consumer failed) { Objects.requireNonNull(failed); //nothing do do , I am a Success return ofNullable(value); } } class Failure extends AbstractResult { private final String errorMessage; public Failure(final String errorMessage) { super(null); this.errorMessage = errorMessage; } @Override public void ifPresentOrElse(Consumer action, Runnable emptyAction) { emptyAction.run(); } @Override public void ifPresentOrElse(final Consumer success, final Consumer failure) { failure.accept(errorMessage); } @Override public void ifPresentOrElseAsync(Consumer action, Runnable emptyAction) { CompletableFuture.runAsync(emptyAction); } @Override public void ifPresentOrElseAsync(Consumer success, Consumer failure) { CompletableFuture.runAsync(() -> failure.accept(errorMessage)); } public Result ifFailed(Consumer failed) { Objects.requireNonNull(failed); failed.accept(errorMessage); // I am a Failure - hold errorMessage, value already null; return this; } } }