// Path: src/main/java/co/unruly/control/result/Introducers.java
// static <IS, OS, X extends Exception> Function<IS, Stream<Result<OS, Exception>>> tryAndUnwrap(ThrowingLambdas.ThrowingFunction<IS, Stream<OS>, X> f) {
//     return tryTo(f).andThen(unwrapSuccesses());
// }
// 
// Path: src/main/java/co/unruly/control/result/Introducers.java
// static <IS, OS, X extends Exception, F> Function<IS, Result<OS, F>> tryTo(
//     ThrowingLambdas.ThrowingFunction<IS, OS, X> throwingFunction,
//     Function<Exception, F> exceptionMapper
// ) {
//     return input -> {
//         try {
//             return Result.success(throwingFunction.apply(input));
//         } catch (Exception ex) {
//             return Result.failure(exceptionMapper.apply(ex));
//         }
//     };
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <T> Function<Result<T, T>, T> collapse() {
//     return r -> r.either(identity(), identity());
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <OS, IS extends OS, FS extends OS, F> Function<Result<IS, F>, OS> ifFailed(Function<F, FS> recoveryFunction) {
//     return r -> r.either(identity(), recoveryFunction);
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <S, IF, OF> Function<Result<S, IF>, Result<S, OF>> onFailure(Function<IF, OF> mappingFunction) {
//     return recover(mappingFunction.andThen(Result::failure));
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <IS, OS, F> Function<Result<IS, F>, Result<OS, F>> onSuccess(Function<IS, OS> mappingFunction) {
//     return attempt(mappingFunction.andThen(Result::success));
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <S, F> Function<Result<Stream<S>, F>, Stream<Result<S, F>>> unwrapSuccesses() {
//     return r -> r.either(
//         successes -> successes.map(Result::success),
//         failure -> Stream.of(Result.failure(failure))
//     );
// }


import org.junit.Test;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static co.unruly.control.result.Introducers.tryAndUnwrap;
import static co.unruly.control.result.Introducers.tryTo;
import static co.unruly.control.result.Resolvers.collapse;
import static co.unruly.control.result.Resolvers.ifFailed;
import static co.unruly.control.result.Transformers.onFailure;
import static co.unruly.control.result.Transformers.onSuccess;
import static co.unruly.control.result.Transformers.unwrapSuccesses;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
package co.unruly.control.result;




//import static co.unruly.control.result.Results.ifFailed;

public class TryTest {

    @Test
    public void canHandleRuntimeExceptions() {
        Function<String, String> doSomething = tryTo(TryTest::throwsRuntimeException)
            .andThen(ifFailed(Exception::getMessage));

        assertThat(doSomething.apply("throw"), is("This is a naughty method"));
        assertThat(doSomething.apply("play nice"), is("Today, I was good"));
    }

    @Test
    public void canHandleCheckedExceptions() {
        Function<String, String> doSomething = tryTo(TryTest::throwsCheckedException)
            .andThen(ifFailed(Exception::getMessage));

        assertThat(doSomething.apply("throw"), is("This is a naughty method"));
        assertThat(doSomething.apply("play nice"), is("Today, I was good"));
    }

    @Test
    public void canHandleStreamFunctionsUsingFlatTry() {
        List<String> doingStuffWithNumbers = Stream.of("1", "two", "3")
            .flatMap(tryAndUnwrap(TryTest::throwsAndMakesStream))
            .map(onSuccess(x -> String.format("Success: %s", x)))
            .map(onFailure(Exception::getMessage))
// Path: src/main/java/co/unruly/control/result/Introducers.java
// static <IS, OS, X extends Exception> Function<IS, Stream<Result<OS, Exception>>> tryAndUnwrap(ThrowingLambdas.ThrowingFunction<IS, Stream<OS>, X> f) {
//     return tryTo(f).andThen(unwrapSuccesses());
// }
// 
// Path: src/main/java/co/unruly/control/result/Introducers.java
// static <IS, OS, X extends Exception, F> Function<IS, Result<OS, F>> tryTo(
//     ThrowingLambdas.ThrowingFunction<IS, OS, X> throwingFunction,
//     Function<Exception, F> exceptionMapper
// ) {
//     return input -> {
//         try {
//             return Result.success(throwingFunction.apply(input));
//         } catch (Exception ex) {
//             return Result.failure(exceptionMapper.apply(ex));
//         }
//     };
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <T> Function<Result<T, T>, T> collapse() {
//     return r -> r.either(identity(), identity());
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <OS, IS extends OS, FS extends OS, F> Function<Result<IS, F>, OS> ifFailed(Function<F, FS> recoveryFunction) {
//     return r -> r.either(identity(), recoveryFunction);
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <S, IF, OF> Function<Result<S, IF>, Result<S, OF>> onFailure(Function<IF, OF> mappingFunction) {
//     return recover(mappingFunction.andThen(Result::failure));
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <IS, OS, F> Function<Result<IS, F>, Result<OS, F>> onSuccess(Function<IS, OS> mappingFunction) {
//     return attempt(mappingFunction.andThen(Result::success));
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <S, F> Function<Result<Stream<S>, F>, Stream<Result<S, F>>> unwrapSuccesses() {
//     return r -> r.either(
//         successes -> successes.map(Result::success),
//         failure -> Stream.of(Result.failure(failure))
//     );
// }


// Path: src/test/java/co/unruly/control/result/TryTest.java
import org.junit.Test;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static co.unruly.control.result.Introducers.tryAndUnwrap;
import static co.unruly.control.result.Introducers.tryTo;
import static co.unruly.control.result.Resolvers.collapse;
import static co.unruly.control.result.Resolvers.ifFailed;
import static co.unruly.control.result.Transformers.onFailure;
import static co.unruly.control.result.Transformers.onSuccess;
import static co.unruly.control.result.Transformers.unwrapSuccesses;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;

package co.unruly.control.result;




//import static co.unruly.control.result.Results.ifFailed;

public class TryTest {

    @Test
    public void canHandleRuntimeExceptions() {
        Function<String, String> doSomething = tryTo(TryTest::throwsRuntimeException)
            .andThen(ifFailed(Exception::getMessage));

        assertThat(doSomething.apply("throw"), is("This is a naughty method"));
        assertThat(doSomething.apply("play nice"), is("Today, I was good"));
    }

    @Test
    public void canHandleCheckedExceptions() {
        Function<String, String> doSomething = tryTo(TryTest::throwsCheckedException)
            .andThen(ifFailed(Exception::getMessage));

        assertThat(doSomething.apply("throw"), is("This is a naughty method"));
        assertThat(doSomething.apply("play nice"), is("Today, I was good"));
    }

    @Test
    public void canHandleStreamFunctionsUsingFlatTry() {
        List<String> doingStuffWithNumbers = Stream.of("1", "two", "3")
            .flatMap(tryAndUnwrap(TryTest::throwsAndMakesStream))
            .map(onSuccess(x -> String.format("Success: %s", x)))
            .map(onFailure(Exception::getMessage))
            .map(collapse())