Skip to content
/ result Public

Java implementation of Result monad

License

Notifications You must be signed in to change notification settings

artkonr/result

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Result

An alternative to try/catch following the design pattern offered by java.util.Optional and Result in Rust.

License: Apache License 2.0 - this library is unconditionally open-source.

Getting started

Library installation is available for Maven and Gradle and targets Java 17.

Maven

<dependencies>
    <dependency>
        <groupId>io.github.artkonr</groupId>
        <artifactId>result</artifactId>
        <version>${versions.result}</version>
    </dependency>
</dependencies>

Gradle

depencencies {
    implementation 'io.github.artkonr:result:${resultVersion}'
}

Cookbook

Functional style

The library is designed to offer a fluent functional-style API to interact with errors, very similar to the API of java.util.Optional:

import java.io.IOException;

public void doingSomeWork() {
    Result<String, RuntimeException> fallibleIO = Result
            .wrap(IOException.class, () -> doSomeIOWork()) // wrap some IO operation
            .map(io -> convertIOResult(io))                // convert item
            .taint(
                    text -> !isTextOk(text),               // check if the value is what we expect
                    text -> createError(text)              // and make and error if it is not
            )
            .mapErr(generic -> wrapError(generic));        // wrap into a domain-specific error

    // we can recover from errors by using fallbacks
    String getOrFallback = fallibleIO.unwrapOr("fallback");
    
    // ... or recover without taking the value out 
    Result<String, RuntimeException> maybeGoOnFromHere = fallibleIO.recover(err -> err.getMessage());

    // ... or just go fingers-crossed
    String couldHurt = fallibleIO.unwrap();

    // if we don't care about the result value,
    // we can always drop it and, say, invoke a callback
    FlagResult<RuntimeException> dropped = fallibleIO.drop();
    dropped.ifOk(() -> System.out.println("well done"));
}

POJO-style

Of course, it is also possible to work in a more traditional way:

import java.io.File;
import java.io.IOException;

public void doingSomeWork() {
    Result<File, IOException> fallibleIO;
    try {
        File file = doSomeIOWork();
        fallibleIO = Result.ok(file);
    } catch (IOException ex) {
        fallibleIO = Result.err(ex);
    }

    if (fallibleIO.isOk()) {
        File okFile = fallibleIO.get();
        readFileContents(okFile);
    } else {
        IOException err = fallibleIO.getErr();
        logError(err);
    }
}

State model

Library API offers a variety of transformation methods, such as:

  • map / mapErr / flatMap - modify the internal state of the monad;
  • fork - OK -> error conversion, matching the error type;
  • taint - OK -> error conversion, broadening the error type;
  • recover - error -> OK conversion;
  • peek - fluent introspection on the state.
  • fuse / join - combining 2 or more results together, respectively;
  • unwrap - taking the value out of the monad and handling possible error.

Building

The library is built with Maven:

mvn clean package

About

Java implementation of Result monad

Resources

License

Stars

Watchers

Forks

Languages