| /* |
| * Copyright 2023 CeresDB Project Authors. Licensed under Apache-2.0. |
| */ |
| package io.ceresdb.models; |
| |
| import java.util.function.Function; |
| |
| import io.ceresdb.common.util.Requires; |
| |
| /** |
| * `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). |
| * |
| */ |
| public final class Result<Ok, Err> { |
| |
| public static final int SUCCESS = 200; |
| public static final int BAD_REQUEST = 400; |
| public static final int FLOW_CONTROL = 503; |
| |
| private final Ok ok; |
| private final Err err; |
| |
| public static <Ok, Err> Result<Ok, Err> ok(final Ok ok) { |
| Requires.requireNonNull(ok, "Null.ok"); |
| return new Result<>(ok, null); |
| } |
| |
| public static <Ok, Err> Result<Ok, Err> err(final Err err) { |
| Requires.requireNonNull(err, "Null.err"); |
| return new Result<>(null, err); |
| } |
| |
| private Result(Ok ok, Err err) { |
| this.ok = ok; |
| this.err = err; |
| } |
| |
| public boolean isOk() { |
| return this.ok != null && this.err == null; |
| } |
| |
| public Ok getOk() { |
| return Requires.requireNonNull(this.ok, "Null.ok"); |
| } |
| |
| public Err getErr() { |
| return Requires.requireNonNull(this.err, "Null.err"); |
| } |
| |
| /** |
| * Maps a `Result<Ok, Err>` to `Result<U, Err>` by applying a function to |
| * a contained [`Ok`] value, leaving an [`Err`] value untouched. |
| * |
| * This function can be used to compose the results of two functions. |
| * |
| * @param mapper a function to a contained [`Ok`] value |
| * @param <U> the [`Ok`] value type to map to |
| * @return `Result<U, Err>` |
| */ |
| public <U> Result<U, Err> map(final Function<Ok, U> mapper) { |
| return isOk() ? Result.ok(mapper.apply(getOk())) : Result.err(getErr()); |
| } |
| |
| /** |
| * Returns the provided default (if [`Err`]), or applies a function to |
| * the contained value (if [`Ok`]). |
| * |
| * Arguments passed to `mapOr` are eagerly evaluated; if you are passing |
| * the result of a function call, it is recommended to use |
| * {@link #mapOrElse(Function, Function)}, which is lazily evaluated. |
| * |
| * @param defaultVal default value (if [`Err`]) |
| * @param mapper a function to a contained [`Ok`] value |
| * @param <U> the value type to map to |
| * @return the provided default (if [`Err`]), or applies a function to |
| * the contained value (if [`Ok`]) |
| */ |
| public <U> U mapOr(final U defaultVal, final Function<Ok, U> mapper) { |
| return isOk() ? mapper.apply(getOk()) : defaultVal; |
| } |
| |
| /** |
| * Maps a `Result<OK, Err>` to `U` by applying a fallback function to a |
| * contained [`Err`] value, or a default function to a contained [`Ok`] |
| * value. |
| * |
| * This function can be used to unpack a successful result while |
| * handling an error. |
| * |
| * @param fallbackMapper a fallback function to a contained [`Err`] value |
| * @param mapper a function to a contained [`Ok`] value |
| * @param <U> the value type to map to |
| * @return `U` by applying a fallback function to a contained [`Err`] value, |
| * or a default function to a contained [`Ok`] value. |
| */ |
| public <U> U mapOrElse(final Function<Err, U> fallbackMapper, final Function<Ok, U> mapper) { |
| return isOk() ? mapper.apply(getOk()) : fallbackMapper.apply(getErr()); |
| } |
| |
| /** |
| * Maps a `Result<Ok, Err>` to `Result<Ok, F>` by applying a function to a |
| * contained [`Err`] value, leaving an [`Ok`] value untouched. |
| * |
| * @param mapper a function to a contained [`Err`] value |
| * @param <F> the err type to map to |
| * @return `Result<Ok, F>` |
| */ |
| public <F> Result<Ok, F> mapErr(final Function<Err, F> mapper) { |
| return isOk() ? Result.ok(getOk()) : Result.err(mapper.apply(getErr())); |
| } |
| |
| /** |
| * Calls `mapper` if the result is [`Ok`], otherwise returns the [`Err`] value. |
| * |
| * @param mapper a function to a contained [`Ok`] value |
| * @param <U> the value type witch mapped to |
| * @return `Result<U, Err>` |
| */ |
| public <U> Result<U, Err> andThen(final Function<Ok, Result<U, Err>> mapper) { |
| return isOk() ? mapper.apply(getOk()) : Result.err(getErr()); |
| } |
| |
| /** |
| * Calls `mapper` if the result is [`Err`], otherwise returns the [`Ok`] value. |
| * |
| * @param mapper a function to a contained [`Err`] value |
| * @param <F> the err type to map to |
| * @return `Result<Ok, Err>` |
| */ |
| public <F> Result<Ok, F> orElse(final Function<Err, Result<Ok, F>> mapper) { |
| return isOk() ? Result.ok(getOk()) : mapper.apply(getErr()); |
| } |
| |
| /** |
| * Returns the contained [`Ok`] value or a provided default. |
| * |
| * @param defaultVal a provided default value |
| * @return the contained [`Ok`] value or a provided default |
| */ |
| public Ok unwrapOr(final Ok defaultVal) { |
| return isOk() ? getOk() : defaultVal; |
| } |
| |
| /** |
| * Returns the contained [`Ok`] value or computes it from a function. |
| * |
| * @param mapper computes function |
| * @return the contained [`Ok`] value or computes it from a function |
| */ |
| public Ok unwrapOrElse(final Function<Err, Ok> mapper) { |
| return isOk() ? getOk() : mapper.apply(getErr()); |
| } |
| |
| @Override |
| public String toString() { |
| return "Result{" + "ok=" + ok + ", err=" + err + '}'; |
| } |
| } |