Skip to content

Commit

Permalink
reverse range
Browse files Browse the repository at this point in the history
  • Loading branch information
tonivade committed Oct 13, 2024
1 parent 6fe3827 commit ec1153d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ static Validator<String, String> maxLength(int length, Producer<String> message)
return lowerThan(length, message).compose(String::length);
}

static <T extends Comparable<T>> Validator<String, T> nonEquals(T value) {
return nonEquals(value, () -> "require non equals to " + value);
}

static <T extends Comparable<T>> Validator<String, T> nonEquals(T value, Producer<String> message) {
return from(input -> input.compareTo(value) != 0, message);
}

static Validator<String, Integer> positive() {
return greaterThan(0);
}
Expand Down
38 changes: 33 additions & 5 deletions core/src/main/java/com/github/tonivade/purefun/data/Range.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,47 @@

import com.github.tonivade.purefun.core.Function1;
import com.github.tonivade.purefun.core.Tuple;

import static com.github.tonivade.purefun.core.Function1.identity;
import static com.github.tonivade.purefun.core.Precondition.check;
import static com.github.tonivade.purefun.core.Precondition.greaterThanOrEquals;
import static com.github.tonivade.purefun.type.Validation.mapN;
import static com.github.tonivade.purefun.type.Validation.requireGreaterThanOrEqual;
import static com.github.tonivade.purefun.type.Validation.requireLowerThan;
import static com.github.tonivade.purefun.type.Validation.requireLowerThanOrEqual;
import static com.github.tonivade.purefun.type.Validation.requireNonEquals;

public record Range(int begin, int end, int increment) implements Iterable<Integer> {

public record Range(int begin, int end) implements Iterable<Integer> {
public Range(int begin, int end) {
this(begin, end, 1);
}

public Range {
check(greaterThanOrEquals(end, begin));
check(() -> increment != 0);
if (increment > 0) {
check(greaterThanOrEquals(end, begin));
} else {
check(greaterThanOrEquals(begin, end));
}
}

public Range reverse() {
return new Range(end, begin, -increment);
}

public boolean contains(int value) {
if (increment < 0) {
return mapN(
requireGreaterThanOrEqual(value, end),
requireLowerThan(value, begin), Tuple::of).isValid();
}
return mapN(
requireGreaterThanOrEqual(value, begin),
requireLowerThan(value, end), Tuple::of).isValid();
}

public int size() {
return end - begin;
return Math.abs(end - begin);
}

public ImmutableArray<Integer> collect() {
Expand All @@ -44,6 +62,9 @@ public <T> ImmutableArray<T> map(Function1<? super Integer, ? extends T> map) {
}

public IntStream intStream() {
if (increment < 0) {
return IntStream.range(end, begin).map(i -> begin - i + end - 1);
}
return IntStream.range(begin, end);
}

Expand All @@ -58,12 +79,19 @@ public Iterator<Integer> iterator() {

@Override
public String toString() {
return String.format("Range(%d..%d)", begin, end);
return String.format("Range(%d..%d, increment=%d)", begin, end, increment);
}

public static Range of(int begin, int end) {
return mapN(
requireLowerThanOrEqual(begin, end),
requireGreaterThanOrEqual(end, begin), Range::new).getOrElseThrow();
}

public static Range of(int begin, int end, int increment) {
return mapN(
requireLowerThanOrEqual(begin, end),
requireGreaterThanOrEqual(end, begin),
requireNonEquals(increment, 0), Range::new).getOrElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static com.github.tonivade.purefun.core.Validator.lowerThan;
import static com.github.tonivade.purefun.core.Validator.lowerThanOrEqual;
import static com.github.tonivade.purefun.core.Validator.nonEmpty;
import static com.github.tonivade.purefun.core.Validator.nonEquals;
import static com.github.tonivade.purefun.core.Validator.nonNullAnd;
import static com.github.tonivade.purefun.core.Validator.positive;
import static com.github.tonivade.purefun.data.Sequence.listOf;
Expand Down Expand Up @@ -247,6 +248,10 @@ static Validation<String, String> requireNonEmpty(String value) {
return nonNullAnd(nonEmpty()).validate(value);
}

static Validation<String, Integer> requireNonEquals(Integer value, int x) {
return nonNullAnd(nonEquals(x)).validate(value);
}

static Validation<String, Integer> requirePositive(Integer value) {
return nonNullAnd(positive()).validate(value);
}
Expand Down
16 changes: 16 additions & 0 deletions core/src/test/java/com/github/tonivade/purefun/data/RangeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ public void range() {
);
}

@Test
public void revRange() {
Range range = Range.of(1, 10).reverse();

assertAll(
() -> assertEquals(0, Range.of(1, 1).reverse().size()),
() -> assertEquals(10, range.begin()),
() -> assertEquals(1, range.end()),
() -> assertEquals(9, range.size()),
() -> assertFalse(range.contains(0)),
() -> assertFalse(range.contains(10)),
() -> assertTrue(range.contains(1)),
() -> assertEquals(arrayOf(9, 8, 7, 6, 5, 4, 3, 2, 1), range.collect())
);
}

@Test
public void validRange() {
assertThrows(IllegalArgumentException.class, () -> Range.of(10, 1));
Expand Down

0 comments on commit ec1153d

Please sign in to comment.