Skip to content

Commit

Permalink
JUnit 5.10.0 + Nahara Toolkit Pipeline a.k.a "Stream API at home"
Browse files Browse the repository at this point in the history
  • Loading branch information
nahkd123 committed Nov 1, 2023
1 parent b6ff2e2 commit c5967c8
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 5 deletions.
2 changes: 1 addition & 1 deletion common/attachments/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion common/configurations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion common/nbtstring/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
Expand Down
18 changes: 18 additions & 0 deletions common/pipeline/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
}

eclipse {
project.name = "Nahara Toolkit - Common - Pipeline"
}

repositories {
mavenCentral()
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
useJUnitPlatform()
}
42 changes: 42 additions & 0 deletions common/pipeline/src/main/java/nahara/common/pipeline/Pipeline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package nahara.common.pipeline;

import java.util.Collections;
import java.util.Iterator;
import java.util.Optional;
import java.util.stream.Stream;

/**
* <p>Represent a pipeline that takes in inputs and yield out outputs.</p>
* <p>Pipelines can be used to filter and transform data, similar to {@link Stream}. I do not know why I made
* this (well ok to be fair I think reusing pipeline transformation could reduce memory usage), but it could
* be useful for someone. Only time will tell I guess?</p>
* @param <I> Input type.
* @param <O> Output type.
*/
public interface Pipeline<I, O> {
public Iterator<O> iteratorOf(Iterator<I> input);

default Iterator<O> iteratorOf(I input) {
return iteratorOf(Collections.singleton(input).iterator());
}

default Iterator<O> iteratorOf(Iterable<I> input) {
return iteratorOf(input.iterator());
}

default Optional<O> firstNonnullOf(Iterator<I> input) {
Iterator<O> iter = iteratorOf(input);

while (iter.hasNext()) {
O obj = iter.next();
if (obj == null) continue;
return Optional.of(obj);
}

return Optional.empty();
}

default Optional<O> firstNonnullOf(I input) {
return firstNonnullOf(Collections.singleton(input).iterator());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package nahara.common.pipeline;

import java.util.function.Function;
import java.util.function.Predicate;

import nahara.common.pipeline.impl.PipelineBuilderImpl;
import nahara.common.pipeline.impl.StartOfPipelineImpl;

public interface PipelineBuilder<I, O> {
public PipelineBuilder<I, O> filter(Predicate<O> predicate);
public <M> PipelineBuilder<I, M> map(Function<O, M> mapper);

// Create and build
public Pipeline<I, O> build();

public static <T> PipelineBuilder<T, T> create() {
return new PipelineBuilderImpl<>(new StartOfPipelineImpl<>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package nahara.common.pipeline.impl;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Predicate;

import nahara.common.pipeline.Pipeline;

public class FilterPipelineImpl<I, O> implements Pipeline<I, O> {
private Pipeline<I, O> previous;
private Predicate<O> predicate;

public FilterPipelineImpl(Pipeline<I, O> previous, Predicate<O> predicate) {
this.previous = previous;
this.predicate = predicate;
}

@Override
public Iterator<O> iteratorOf(Iterator<I> input) {
return new Iterator<O>() {
private O nextObj = null;
private boolean holdingNextObj = false, isEnded = false;
private Iterator<O> prevIter = previous.iteratorOf(input);

@Override
public boolean hasNext() {
if (isEnded) return false;
if (!holdingNextObj) {
while (prevIter.hasNext()) {
O obj = prevIter.next();
if (!predicate.test(obj)) continue;

holdingNextObj = true;
nextObj = obj;
return true;
}

isEnded = true;
return false;
}

return true;
}

@Override
public O next() {
if (!holdingNextObj) {
if (isEnded || !hasNext()) throw new NoSuchElementException();
}

holdingNextObj = false;
return nextObj;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package nahara.common.pipeline.impl;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;

import nahara.common.pipeline.Pipeline;

public class MapPipelineImpl<I, M, O> implements Pipeline<I, O> {
private Pipeline<I, M> previous;
private Function<M, O> mapper;

public MapPipelineImpl(Pipeline<I, M> previous, Function<M, O> mapper) {
this.previous = previous;
this.mapper = mapper;
}

@Override
public Iterator<O> iteratorOf(Iterator<I> input) {
return new Iterator<O>() {
private O nextObj = null;
private boolean holdingNextObj = false, isEnded = false;
private Iterator<M> prevIter = previous.iteratorOf(input);

@Override
public boolean hasNext() {
if (isEnded) return false;
if (!holdingNextObj) {
if (!prevIter.hasNext()) {
isEnded = true;
return false;
}

holdingNextObj = true;
nextObj = mapper.apply(prevIter.next());
return true;
}

return true;
}

@Override
public O next() {
if (!holdingNextObj) {
if (isEnded || !hasNext()) throw new NoSuchElementException();
}

holdingNextObj = false;
return nextObj;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package nahara.common.pipeline.impl;

import java.util.function.Function;
import java.util.function.Predicate;

import nahara.common.pipeline.Pipeline;
import nahara.common.pipeline.PipelineBuilder;

public class PipelineBuilderImpl<I, O> implements PipelineBuilder<I, O> {
private Pipeline<I, O> current;

public PipelineBuilderImpl(Pipeline<I, O> current) {
this.current = current;
}

@Override
public PipelineBuilder<I, O> filter(Predicate<O> predicate) {
current = new FilterPipelineImpl<>(current, predicate);
return this;
}

@Override
public <M> PipelineBuilder<I, M> map(Function<O, M> mapper) {
return new PipelineBuilderImpl<>(new MapPipelineImpl<>(current, mapper));
}

@Override
public Pipeline<I, O> build() {
return current;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package nahara.common.pipeline.impl;

import java.util.Iterator;

import nahara.common.pipeline.Pipeline;

public class StartOfPipelineImpl<I> implements Pipeline<I, I> {
@Override
public Iterator<I> iteratorOf(Iterator<I> input) {
return input;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package nahara.common.pipeline;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class PipelineTest {
@Test
void testMapping() {
var pipeline = PipelineBuilder.<String>create()
.map(v -> Integer.parseInt(v))
.map(v -> v + 1)
.filter(v -> v != 0)
.build();
assertEquals(124, pipeline.firstNonnullOf("123").orElseThrow());
assertTrue(pipeline.firstNonnullOf("-1").isEmpty());
}
}
2 changes: 1 addition & 1 deletion common/structures/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion common/tasks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

tasks.named('test') {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
'common/configurations',
'common/localize',
'common/nbtstring',
'common/pipeline',
'common/structures',
'common/tasks',

Expand Down

0 comments on commit c5967c8

Please sign in to comment.