Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TriState toBoolean helper methods #472

Merged
merged 1 commit into from Oct 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.
}
}