Skip to content

Commit

Permalink
Simplify SafeLong implementation (#2073)
Browse files Browse the repository at this point in the history
Simplify SafeLong implementation
  • Loading branch information
carterkozak authored Aug 7, 2023
1 parent fdbb011 commit 8bf8b0f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 17 deletions.
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-2073.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: improvement
improvement:
description: Simplify SafeLong implementation
links:
- https://github.com/palantir/conjure-java/pull/2073
3 changes: 0 additions & 3 deletions conjure-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,5 @@ dependencies {
testImplementation 'org.assertj:assertj-core'
testImplementation 'com.palantir.safe-logging:preconditions-assertj'
testImplementation 'org.junit.jupiter:junit-jupiter'

annotationProcessor 'org.immutables:value'
compileOnly 'org.immutables:value::annotations'
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,68 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.palantir.logsafe.Preconditions;
import org.immutables.value.Value;

/** A wrapper around a long which is safe for json-serialization as a number without loss of precision. */
@Value.Immutable
public abstract class SafeLong implements Comparable<SafeLong> {
public final class SafeLong implements Comparable<SafeLong> {

private static final long MIN_SAFE_VALUE = -(1L << 53) + 1;
private static final long MAX_SAFE_VALUE = (1L << 53) - 1;

public static final SafeLong MAX_VALUE = SafeLong.of(MAX_SAFE_VALUE);
public static final SafeLong MIN_VALUE = SafeLong.of(MIN_SAFE_VALUE);

private final long longValue;

private SafeLong(long longValue) {
this.longValue = check(longValue);
}

@JsonValue
@Value.Parameter
public abstract long longValue();
public long longValue() {
return longValue;
}

@Value.Check
protected final void check() {
private static long check(long value) {
Preconditions.checkArgument(
MIN_SAFE_VALUE <= longValue() && longValue() <= MAX_SAFE_VALUE,
MIN_SAFE_VALUE <= value && value <= MAX_SAFE_VALUE,
"number must be safely representable in javascript i.e. "
+ "lie between -9007199254740991 and 9007199254740991");
return value;
}

public static SafeLong valueOf(String value) {
return SafeLong.of(Long.parseLong(value));
return of(Long.parseLong(value));
}

@JsonCreator
public static SafeLong of(long value) {
return ImmutableSafeLong.of(value);
return new SafeLong(value);
}

@Override
public String toString() {
return Long.toString(longValue);
}

@Override
public int compareTo(SafeLong other) {
return Long.compare(longValue, other.longValue);
}

@Override
public final String toString() {
return Long.toString(longValue());
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
SafeLong safeLong = (SafeLong) other;
return longValue == safeLong.longValue;
}

@Override
public final int compareTo(SafeLong other) {
return Long.compare(longValue(), other.longValue());
public int hashCode() {
return 177573 + Long.hashCode(longValue);
}
}

0 comments on commit 8bf8b0f

Please sign in to comment.