LogoLogo
GitHubFree book
  • 🏠Introduction
  • Using the Library
    • ðŸŒąGetting Started
      • Adding Result to Your Build
      • Creating Results
    • ðŸŠīBasic Usage
      • Checking Success or Failure
      • Unwrapping Values
      • Conditional Actions
    • 🚀Advanced Usage
      • Screening Results
      • Transforming Results
    • 🏁Recap
  • Add-ons
    • ðŸ’ĪLazy Results
    • ðŸ—ĢïļFluent Assertions
    • 📜Jackson Module
    • 🧑‍🚀Micronaut Serialization
  • Other resources
    • ðŸ“ĶBill of Materials
    • 📈Benchmarks
    • ðŸĪ–Demo Projects
      • Spring Boot Demo Project
      • Micronaut Demo Project
    • ⚖ïļLicense
Powered by GitBook
LogoLogo

Source Code

  • GitHub
  • License

Quality

  • SonarCloud
  • Benchmarks

Documentation

  • Free book
  • Javadoc

Releases

  • Maven Central
  • Bill of Materials

Copyright 2024 Guillermo Calvo

On this page
  • Successful Results
  • Failed Results
  • Results Based on Nullable Values
  • Results Based on Optionals
  • Results Based on Callables
  • Conclusion

Was this helpful?

Edit on GitHub
Export as PDF
  1. Using the Library
  2. Getting Started

Creating Results

How to instantiate new Result objects

PreviousAdding Result to Your BuildNextBasic Usage

Last updated 8 months ago

Was this helpful?

There are several ways to create result objects.

Successful Results

A successful result contains a non-null value produced by an operation when everything works as intended. We can use to create a new instance.

@Test
void testSuccess() {
  // When
  Result<Integer, ?> result = Results.success(200);
  // Then
  assertTrue(result::hasSuccess);
  assertFalse(result::hasFailure);
}

Note that we can invoke or to check whether a result is successful or failed (more on this in the ).

Failed Results

On the other hand, a failed result holds a value representing the problem that prevented the operation from completing. We can use to create a new one.

@Test
void testFailure() {
  // When
  Result<?, String> result = Results.failure("The operation failed");
  // Then
  assertTrue(result::hasFailure);
  assertFalse(result::hasSuccess);
}

Failure values cannot be null either.

Results Based on Nullable Values

@Test
void testOfNullable() {
  // Given
  String string1 = "The operation succeeded";
  String string2 = null;
  // When
  Result<String, Integer> result1 = Results.ofNullable(string1, 404);
  Result<String, Integer> result2 = Results.ofNullable(string2, 404);
  // Then
  assertTrue(result1::hasSuccess);
  assertTrue(result2::hasFailure);
}

The second argument can be either a failure value or a function that produces a failure value.

Results Based on Optionals

@Test
void testOfOptional() {
  // Given
  Optional<BigDecimal> optional1 = Optional.of(BigDecimal.ONE);
  Optional<BigDecimal> optional2 = Optional.empty();
  // When
  Result<BigDecimal, Integer> result1 = Results.ofOptional(optional1, -1);
  Result<BigDecimal, Integer> result2 = Results.ofOptional(optional2, -1);
  // Then
  assertTrue(result1::hasSuccess);
  assertTrue(result2::hasFailure);
}

Results Based on Callables

String task1() {
  return "OK";
}

String task2() throws Exception {
  throw new Exception("Whoops!");
}

@Test
void testOfCallable() {
  // When
  Result<String, Exception> result1 = Results.ofCallable(this::task1);
  Result<String, Exception> result2 = Results.ofCallable(this::task2);
  // Then
  assertTrue(result1::hasSuccess);
  assertTrue(result2::hasFailure);
}

This method enables compatibility with legacy or third-party code that uses exceptions to indicate operation failure.

Conclusion

We've covered how to create new instances of Result using various factory methods provided by the Results class. Each method serves a specific purpose, allowing you to select the most suitable one based on the situation.

When we need to create results that depend on a possibly null value, we can use . If the first argument is null, then the second one will be used to create a failed result.

We can also use to create results that depend on an value. If the first argument is an empty optional, then the second one will be used to create a failed result.

The second argument can be a too.

Finally, if we have a task that may either return a success value or throw an exception, we can encapsulate it as a result using so we don't need to use a try-catch block.

ðŸŒą
Results::success
Result::hasSuccess
Result::hasFailure
next section
Results::failure
Results::ofNullable
Results::ofOptional
Optional
Supplier
Results::ofCallable