Skip to content

Commit

Permalink
Add TriState toBoolean helper methods
Browse files Browse the repository at this point in the history
While the TriState enum already has helper methods to quickly convert a
boolean into a TriState (both nullable wrappers and their primitive
counterparts), helper methods to convert a TriState back into a boolean
representation are currently missing.

This commit introduces two methods that do exactly that, one
allowing a straight forward conversion to a Boolean as it can represent
a TriState through its nullability as well as another method that
discards the TriState#NOT_SET by accepting a supplier that will be
used to map a not set tri-state.
  • Loading branch information
lynxplay committed Oct 8, 2021
1 parent f5253d0 commit b1550bf
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
55 changes: 55 additions & 0 deletions api/src/main/java/net/kyori/adventure/util/TriState.java
Expand Up @@ -23,6 +23,7 @@
*/
package net.kyori.adventure.util;

import java.util.function.BooleanSupplier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -51,6 +52,60 @@ public enum TriState {
*/
TRUE;

/**
* Converts this tri-state back into a {@link Boolean}.
*
* @return the boolean representing this tri-state. {@link #NOT_SET} will be represented by {@code null}.
* @since 4.10.0
*/
public @Nullable Boolean toBoolean() {
switch (this) {
case TRUE: return Boolean.TRUE;
case FALSE: return Boolean.FALSE;
default: return null;
}
}

/**
* Converts this tri-state back into a {@code boolean}.
*
* <p>As the {@link #NOT_SET} state cannot be represented by the boolean type, this
* method maps the {@link #NOT_SET} state to other passed boolean value.
* This method may hence also be viewed as an equivalent to {@link
* java.util.Optional#orElse(Object)}.</p>
*
* @param other the boolean value that should be returned if this tri-state is {@link #NOT_SET}.
* @return the boolean representing the tri-state or the boolean passed if this state is {@link #NOT_SET}.
* @since 4.10.0
*/
public boolean toBooleanOrElse(final boolean other) {
switch (this) {
case TRUE: return true;
case FALSE: return false;
default: return other;
}
}

/**
* Converts this tri-state back into a {@code boolean}.
*
* <p>As the {@link #NOT_SET} state cannot be represented by the boolean type, this
* method maps the {@link #NOT_SET} state to the suppliers result.
* This method may hence also be viewed as an equivalent to {@link
* java.util.Optional#orElseGet(java.util.function.Supplier)}.</p>
*
* @param supplier the supplier that will be executed to produce the value that should be returned if this tri-state is {@link #NOT_SET}.
* @return the boolean representing the tri-state or the result of the passed supplier if this state is {@link #NOT_SET}.
* @since 4.10.0
*/
public boolean toBooleanOrElseGet(final @NotNull BooleanSupplier supplier) {
switch (this) {
case TRUE: return true;
case FALSE: return false;
default: return supplier.getAsBoolean();
}
}

/**
* Gets a state from a {@code boolean}.
*
Expand Down
38 changes: 38 additions & 0 deletions api/src/test/java/net/kyori/adventure/util/TriStateTest.java
Expand Up @@ -23,9 +23,14 @@
*/
package net.kyori.adventure.util;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class TriStateTest {
@Test
Expand All @@ -40,4 +45,37 @@ void testByBooleanBoxed() {
assertEquals(TriState.FALSE, TriState.byBoolean(Boolean.FALSE));
assertEquals(TriState.TRUE, TriState.byBoolean(Boolean.TRUE));
}

@Test
void testToBoolean() {
assertEquals(true, TriState.TRUE.toBoolean());
assertEquals(false, TriState.FALSE.toBoolean());
assertNull(TriState.NOT_SET.toBoolean());
}

@Test
void testToBooleanOrElse() {
assertTrue(TriState.TRUE.toBooleanOrElse(false));
assertFalse(TriState.FALSE.toBooleanOrElse(true));

assertTrue(TriState.NOT_SET.toBooleanOrElse(true));
assertFalse(TriState.NOT_SET.toBooleanOrElse(false));
}

@Test
void testToBooleanOrElseGet() {
final AtomicInteger atomicCounter = new AtomicInteger(0);
final Function<Boolean, Boolean> supplierCounter = b -> {
atomicCounter.incrementAndGet();
return b;
};

assertTrue(TriState.TRUE.toBooleanOrElseGet(() -> supplierCounter.apply(false)));
assertFalse(TriState.FALSE.toBooleanOrElseGet(() -> supplierCounter.apply(true)));

assertTrue(TriState.NOT_SET.toBooleanOrElseGet(() -> supplierCounter.apply(true)));
assertFalse(TriState.NOT_SET.toBooleanOrElseGet(() -> supplierCounter.apply(false)));

assertEquals(2, atomicCounter.get()); // Ensure that the supplier was only called twice for the two test cases.
}
}

0 comments on commit b1550bf

Please sign in to comment.