Created
March 22, 2023 16:26
-
-
Save RyanMagnusson/c8719474936f7968be928efe7bc5315c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.examples.tostring; | |
import com.fasterxml.jackson.annotation.JsonGetter; | |
import com.fasterxml.jackson.core.JsonProcessingException; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import lombok.AccessLevel; | |
import lombok.Getter; | |
import lombok.Setter; | |
import lombok.ToString; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.util.function.Supplier; | |
import java.util.stream.Stream; | |
import static java.util.Objects.isNull; | |
import static org.assertj.core.api.Assertions.assertThat; | |
public enum Operator { | |
PLUS("+"), MINUS("-"), MULTIPLY("*"); | |
@Getter @Setter(AccessLevel.NONE) | |
private String symbol; | |
Operator(String symbol) { this.symbol = symbol; } | |
} | |
interface Value extends Supplier<Integer> { | |
static final Logger LOGGER = LoggerFactory.getLogger(Value.class); | |
static Stream<Value> values() { | |
return Stream.of(new One(), new Two(), new Three(), new Four(), new Five(), new Six(), new Seven(), new Eight(), new Nine(), new Ten()); | |
} | |
default Value computeWith(Operator op, Value other) { | |
final Value value = isNull(other) ? new Zero() : other; | |
Value result = null; | |
switch(op) { | |
case PLUS: | |
result = values().filter(val -> val.get() == (get() + value.get())).findFirst().orElse(null); | |
if (result == null) { | |
throw new IndexOutOfBoundsException(String.format("Computing value %d + %d exceeds the limit of 10", get(), value.get())); | |
} | |
System.out.println(String.format("[INFO] Computed value %d + %d to equal %d", get(), value.get(), result.get())); | |
return result; | |
case MINUS: | |
result = values().filter(val -> val.get() == (get() - value.get())).findFirst().orElse(null); | |
if (result == null) { | |
throw new IndexOutOfBoundsException(String.format("Computing value %d - %d exceeds the lower boundary of 0", get(), value.get())); | |
} | |
System.out.println(String.format("[INFO] Computed value %d - %d to equal %d", get(), value.get(), result.get())); | |
return result; | |
case MULTIPLY: | |
if (value.get() == 0) { | |
return new Zero(); | |
} | |
final int computed = get() * value.get(); | |
result = values().filter(val -> val.get() == get() * value.get()).findFirst().orElse(null); | |
if (result == null) { | |
throw new IndexOutOfBoundsException(String.format("Computing value %d * %d, which is: %d, exceeds the boundary of 0 to 10", get(), value.get(), computed)); | |
} | |
System.out.println(String.format("[INFO] Computed value %d * %d to equal %d", get(), value.get(), result.get())); | |
return result; | |
default: | |
final String message = String.format("Unknown operation: %d %s %d", get(), op.getSymbol(), value.get()); | |
System.out.println("[INFO] " + message); | |
throw new UnsupportedOperationException(message); | |
} | |
} | |
} | |
@ToString | |
class Zero implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 0; } | |
} | |
@ToString | |
class One implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 1; } | |
} | |
@ToString | |
class Two implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 2; } | |
} | |
@ToString | |
class Three implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 3; } | |
} | |
@ToString | |
class Four implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 4; } | |
} | |
@ToString | |
class Five implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 5; } | |
} | |
@ToString | |
class Six implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 6; } | |
} | |
@ToString | |
class Seven implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 7; } | |
} | |
@ToString | |
class Eight implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 8; } | |
} | |
@ToString | |
class Nine implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 9; } | |
} | |
@ToString | |
class Ten implements Value { | |
@Override @JsonGetter("value") | |
public Integer get() { return 10; } | |
} | |
class Abacus { | |
final static Logger LOGGER = LoggerFactory.getLogger(Abacus.class); | |
public static void main(String[] args) { | |
final Value start = new Zero(); | |
Value computedValue = start.computeWith(Operator.PLUS, new Two()); | |
assertThat(computedValue).isNotNull(); | |
assertThat(computedValue.get()).isEqualTo(2); | |
computedValue = computedValue.computeWith(Operator.PLUS, new Five()); | |
assertThat(computedValue.get()).isEqualTo(7); | |
computedValue = computedValue.computeWith(Operator.MINUS, new Four()); | |
assertThat(computedValue.get()).isEqualTo(3); | |
computedValue = computedValue.computeWith(Operator.MULTIPLY, new Three()); | |
assertThat(computedValue.get()).isEqualTo(9); | |
Value.values().forEach(val -> System.out.println(String.format("[WARN] @Lombok #toString[%d]: %s", val.get(), val.toString()))); | |
final ObjectMapper mapper = new ObjectMapper(); | |
Value.values().forEach(val -> { | |
try { | |
System.out.println(String.format("w/Jackson #toString[%d]: %s", val.get(), mapper.writeValueAsString(val))); | |
} catch (JsonProcessingException e) { | |
throw new RuntimeException(e); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment