From 65a3f96293377b240154708aa33737b4577b2176 Mon Sep 17 00:00:00 2001 From: Carter Kozak Date: Wed, 30 Jun 2021 08:27:11 -0400 Subject: [PATCH] Replace HumanReadableByteCount `getSize`/`getUnit` with more obvious `map(func)` (#286) Replace HumanReadableByteCount `getSize`/`getUnit` with more obvious `map(func)` --- changelog/@unreleased/pr-286.v2.yml | 6 +++ .../HumanReadableByteCount.java | 40 +++++++++++++++++++ .../HumanReadableByteCountTests.java | 16 ++++++++ 3 files changed, 62 insertions(+) create mode 100644 changelog/@unreleased/pr-286.v2.yml diff --git a/changelog/@unreleased/pr-286.v2.yml b/changelog/@unreleased/pr-286.v2.yml new file mode 100644 index 00000000..d7ab0358 --- /dev/null +++ b/changelog/@unreleased/pr-286.v2.yml @@ -0,0 +1,6 @@ +type: improvement +improvement: + description: Replace HumanReadableByteCount `getSize`/`getUnit` with more obvious + `map(func)` + links: + - https://github.com/palantir/human-readable-types/pull/286 diff --git a/human-readable-types/src/main/java/com/palantir/humanreadabletypes/HumanReadableByteCount.java b/human-readable-types/src/main/java/com/palantir/humanreadabletypes/HumanReadableByteCount.java index fa98c3c2..477bb11a 100644 --- a/human-readable-types/src/main/java/com/palantir/humanreadabletypes/HumanReadableByteCount.java +++ b/human-readable-types/src/main/java/com/palantir/humanreadabletypes/HumanReadableByteCount.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import com.google.errorprone.annotations.DoNotCall; import com.palantir.logsafe.Preconditions; import com.palantir.logsafe.SafeArg; import java.io.Serializable; @@ -172,16 +173,55 @@ private HumanReadableByteCount(long size, ByteUnit unit) { this.unit = Preconditions.checkNotNull(unit, "unit must not be null"); } + /** + * Reads the value of this {@link HumanReadableByteCount} as a tuple of quantity and unit. + * Unlike {@link #getSize()}, this API is meant to make it obvious that the data is only meaningful + * when both pieces are used together. + * + * @param Result type. + */ + @FunctionalInterface + public interface SizeFunction { + + /** + * A method allowing the raw quantity and unit values to be interpreted into a more specific type. + * + * @param quantity Raw number of the given {@code unit} + * @param unit Unit which the {@code quantity represents} + * @return A representation of the byte-count value + */ + T apply(long quantity, ByteUnit unit); + } + + /** + * Provides the value of this {@link HumanReadableByteCount} as a tuple of quantity and unit to the + * {@link SizeFunction}. + * + * @param Result type. + */ + public T map(SizeFunction function) { + Preconditions.checkNotNull(function, "function must not be null"); + return Preconditions.checkNotNull(function.apply(size, unit), "result must not be null"); + } + /** * The size of this byte string in {@link HumanReadableByteCount.ByteUnit binary units}. + * + * @deprecated in favor of {@link #map(SizeFunction)} which is harder to misuse. */ + @DoNotCall + @Deprecated public long getSize() { return size; } /** * The {@link ByteUnit binary unit} of this byte string. + * + * @deprecated in favor of {@link #map(SizeFunction)} which is harder to misuse. */ + @DoNotCall + @Deprecated public ByteUnit getUnit() { return unit; } diff --git a/human-readable-types/src/test/java/com/palantir/humanreadabletypes/HumanReadableByteCountTests.java b/human-readable-types/src/test/java/com/palantir/humanreadabletypes/HumanReadableByteCountTests.java index ad009b0d..d8d100fd 100644 --- a/human-readable-types/src/test/java/com/palantir/humanreadabletypes/HumanReadableByteCountTests.java +++ b/human-readable-types/src/test/java/com/palantir/humanreadabletypes/HumanReadableByteCountTests.java @@ -22,6 +22,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; +import com.palantir.humanreadabletypes.HumanReadableByteCount.ByteUnit; +import com.palantir.logsafe.exceptions.SafeNullPointerException; import java.util.Arrays; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -114,6 +116,20 @@ public void testToJsonString() throws Exception { assertThat(toJsonString(HumanReadableByteCount.valueOf("2 bytes"))).isEqualTo("\"2 bytes\""); } + @Test + public void testMapNulls() { + HumanReadableByteCount bytes = HumanReadableByteCount.valueOf("1 byte"); + assertThatThrownBy(() -> bytes.map(null)).isInstanceOf(SafeNullPointerException.class); + assertThatThrownBy(() -> bytes.map((_val, _unit) -> null)).isInstanceOf(SafeNullPointerException.class); + } + + @Test + public void testMap() { + HumanReadableByteCount bytes = HumanReadableByteCount.valueOf("5mb"); + assertThat(bytes.map((_quantity, unit) -> unit)).isEqualTo(ByteUnit.MiB); + assertThat(bytes.map((quantity, _unit) -> quantity)).isEqualTo(5L); + } + private static void assertStringsEqualToBytes(long expectedBytes, String... byteCounts) { assertThat(Arrays.stream(byteCounts) .map(HumanReadableByteCountTests::parseFromString)