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

javascalautils.Try Maven / Gradle / Ivy

There is a newer version: 1.11.2
Show newest version
/**
 * Copyright 2015 Peter Nerg
 *
 *  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 javascalautils;

import java.util.Iterator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * The Try type represents a computation that may either result in an exception, or return a successfully computed value. 
* Typical use case is situations where parallel computation takes place resulting in more than one response where it's possible that one or more computations * fail.
* Though it might not be desirable to raise an exception for failed computations hence the Try acts a place holder for a response that is either failed or * successful.
* Instances of Try, are either an instance of {@link Success} or {@link Failure}.
* Example of usage:
* *
* *
 * Try<SomeData> getSomeData(SomeInput input) {
 *     try {
 *         // readUserFromDB throws if no user exists
 *         SomeData data = readUserFromDB(input);
 *         return new Success<>(data);
 *     } catch (SomeException ex) {
 *         return new Failure<>(ex);
 *     }
 * }
 * 
* *
* * A more elaborate way is to provide a {@link ThrowableFunction0 checked function} provided to the {@link #apply(ThrowableFunction0)} method.
* *
* *
 * Try<Integer> resultSuccess = Try.apply(() -> 9 / 3); // results in Success(3)
 * Try<Integer> resultFailure = Try.apply(() -> 9 / 0); // results in Failure(ArithmeticException)
 * 
* *
* * Or let us re-write the first example to use the {@link #apply(ThrowableFunction0)} method.
* *
* *
 * Try<SomeData> getSomeData(SomeInput input) {
 *     // readUserFromDB throws if no user exists
 *     Try.apply(() -> readUserFromDB(input));
 * }
 * 
* *
* * To make it even more concise we can create Try instances just by using {@link TryCompanion#Try(ThrowableFunction0) Try(ThrowableFunction0)}.
* This however requires you to statically import the proper methods from the {@link TryCompanion companion class} related to Try. * *
* *
 * import static javascalautils.TryCompanion.Try;
 * 
 * Try<SomeData> getSomeData(SomeInput input) {
 *     // readUserFromDB throws if no user exists
 *     Try(() -> readUserFromDB(input));
 * }
 * 
* *
* * * @author Peter Nerg * @since 1.0 * @param * The type of the value represented by this Try */ public interface Try extends Iterable { /** * Creates an instance of Try.
* If a null or non-throwable value is provided then {@link Success} is returned containing the value, else {@link Failure} containing the * provided throwable. * * @param * The type for the Try * @param value * The value for this to create a Try * @return The Try instance * @since 1.0 */ static Try apply(T value) { return value instanceof Throwable ? new Failure<>((Throwable) value) : new Success<>(value); } /** * Creates an instance of Try wrapping the result of the provided function.
* If the function results in a value then {@link Success} with the value is returned.
* In case the function raises an exception then {@link Failure} is returned containing that exception.
* If null is provided as argument then the {@link #apply(Object)} is invoked.
* Example simple division by zero results in an exception. * *
* *
     * Try<Integer> resultSuccess = Try.apply(() -> 9 / 3); // results in Success(3)
     * Try<Integer> resultFailure = Try.apply(() -> 9 / 0); // results in Failure(ArithmeticException)
     * 
* *
* * @param * The type for the Try * @param function * The function to render either the value T or raise an exception. * @return The resulting Try instance wrapping what the function resulted in * @since 1.3 */ static Try apply(ThrowableFunction0 function) { if (function == null) { return apply((T) null); } try { return new Success<>(function.apply()); } catch (Throwable ex) { return new Failure<>(ex); } } /** * Returns true if the Try is a {@link Failure}, false otherwise. * * @return If the Try is a {@link Failure} * @since 1.0 */ default boolean isFailure() { return !isSuccess(); } /** * Returns true if the Try is a {@link Success}, false otherwise. * * @return If the Try is a {@link Success} * @since 1.0 */ boolean isSuccess(); /** * Returns the value from this {@link Success} or the value provided by the supplier if this is a {@link Failure}. * * @param supplier * The supplier to return the value in case of a {@link Failure} * @return The value from the Try or the supplier * @since 1.0 */ T getOrElse(Supplier supplier); /** * Returns the value if it is a {@link Success}, else null. * * @return The value of the Try or null. * @since 1.0 */ default T orNull() { return getOrElse(() -> null); } /** * Returns this Try if it's a {@link Success} or the value provided by the supplier if this is a {@link Failure}. * * @param supplier * The supplier to return the value in case of a {@link Failure} * @return This try or the value from the supplier */ Try orElse(Supplier> supplier); /** * Returns the value from this {@link Success} or throws the exception if this is a {@link Failure}. * * @return The value of the {@link Success} * @throws Throwable * The Throwable in case of a {@link Failure} * @since 1.0 */ T get() throws Throwable; /** * Completes this Try with an exception wrapped in a {@link Success}.
* The exception is either the exception that the Try failed with (if a {@link Failure}) or an 'UnsupportedOperationException'. * * @return The value of the {@link Failure} in a {@link Success} * @since 1.0 */ Try failed(); /** * Applies the predicate to the value of the {@link Try} and either returns the Try if the predicate matched or a {@link Failure}.
* One of the three outcomes are applicable: *
    *
  • Instance is {@link Success} and predicate matches -> return this
  • *
  • Instance is {@link Success} and predicate does not match -> return {@link Failure}
  • *
  • Instance is {@link Failure} -> return this
  • *
  • *
* * @param filter * The filter to apply * @return The try matching the filter, either this if matching or a {@link Failure} in case no match * @since 1.4 */ Try filter(Predicate filter); /** * Returns the Try's value in an {@link Iterator} if it is a {@link Success}, or an empty {@link Iterator} if it is Failure.
* * @return The iterator for the Try * @since 1.0 */ Iterator iterator(); /** * Maps the given function to the value from this {@link Success} or returns this if this is a {@link Failure}.
* This allows for mapping a {@link Try} containing some type to some completely different type.
* The example converts a {@link Try} of type String to Integer.
* *
     * Try<String> t = ...
     * Try<Integer> t2 = t.map(v -> v.length);
     * 
* *
* * @param * The type for the return value from the function * @param function * The function to use * @return The Option containing the mapped value * @since 1.0 */ Try map(Function function); /** * Maps the given function to the value from this {@link Success} or returns this if this is a {@link Failure}. * * @param * The type for the return value from the function * @param function * The function to use * @return The Option containing the mapped value * @since 1.2 */ Try flatMap(Function> function); /** * Creates a new {@link Try} that in case this {@link Try} is a {@link Failure} will apply the function to recover to a {@link Success}.
* Should this be a {@link Success} then this is returned, i.e. no new instance is created.
* This is a kind of {@link #map(Function)} for failures only.
* E.g.
* In case of t being successful then that value is passed on to recovered, in case of failure then the recover function kicks in and returns * the message from the throwable. * *
* *
     * Try<String> t = ...
     * Try<String> recovered = t.recover(t -> t.getMessage());
     * 
     * 
* *
* * This statement will be Success(3)
Try<Integer> t = Try(() -> 9/3).recover(t -> 0)

* Whilst this statement will be Success(0) as it is division-by-zero
Try<Integer> t = Try(() -> 9/0).recover(t -> * 0)
* * * @param function * The function to apply in case of a {@link Failure} * @return The recovered Try * @since 1.4 */ Try recover(Function function); /** * Creates a new {@link Try} that in case this {@link Try} is a {@link Failure} will apply the function to recover the {@link Try} rendered by the * function.
* Should this be a {@link Success} the value is propagated as-is.
* This is a kind of {@link #map(Function)} for failures only.
* E.g. * *
* *
     * Try<String> t = ...
     * Try<String> recovered = t.recover(t -> new Success<>(t.getMessage()));
     * 
* *
* * In case of t being successful then that value is passed on to recovered, in case of failure then the recover function kicks in and returns * the a {@link Success} with message from the throwable. * * * @param function * The function to apply in case of a {@link Failure} * @return The recovered Try * @since 1.4 */ Try recoverWith(Function> function); /** * Returns the Try's value in a Stream if it is a {@link Success}, or an empty Stream if it is a {@link Failure}. * * @return The stream for the Try * @since 1.0 */ Stream stream(); /** * Returns this {@link Try} as an {@link Option}.
* If it is a {@link Success} then the value is wrapped in {@link Some} else {@link None} is returned.
* Should the {@link Success} contain a null value the result will be {@link None} as null values are per definition * none/nothing. * * @return The {@link Option} representing this Try * @since 1.0 */ default Option asOption() { return Option.apply(orNull()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy