diff --git a/build.gradle b/build.gradle index 7c3ad29..1ddc5b2 100644 --- a/build.gradle +++ b/build.gradle @@ -32,14 +32,14 @@ repositories { dependencies { implementation('net.dv8tion:JDA:5.0.0-beta.21') - compileOnly('dev.latvian.apps:ansi:1.0.0-build.3') - implementation('dev.latvian.apps:tiny-java-server:1.0.0-build.11') + compileOnly('dev.latvian.apps:ansi:1.0.0-build.4') + implementation('dev.latvian.apps:tiny-java-server:1.0.0-build.18') implementation('org.mongodb:mongodb-driver-sync:5.0.0') // implementation('org.slf4j:slf4j-simple:2.0.5') // implementation('com.google.guava:guava:31.1-jre') { exclude group: "com.google.code.findbugs" } compileOnly('org.jetbrains:annotations:24.0.1') - testImplementation('dev.latvian.apps:ansi:1.0.0-build.3') + testImplementation('dev.latvian.apps:ansi:1.0.0-build.4') testImplementation('org.junit.jupiter:junit-jupiter-api:5.10.0') testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.10.0') testImplementation('junit:junit:4.13.2') diff --git a/src/main/java/dev/latvian/apps/webutils/data/HexId32.java b/src/main/java/dev/latvian/apps/webutils/data/HexId32.java index b896b31..39af554 100644 --- a/src/main/java/dev/latvian/apps/webutils/data/HexId32.java +++ b/src/main/java/dev/latvian/apps/webutils/data/HexId32.java @@ -1,12 +1,12 @@ package dev.latvian.apps.webutils.data; import dev.latvian.apps.webutils.html.Tag; -import dev.latvian.apps.webutils.html.TagConvertible; +import dev.latvian.apps.webutils.html.TagFunction; import java.util.function.BiConsumer; import java.util.function.IntSupplier; -public class HexId32 implements TagConvertible, IntSupplier { +public class HexId32 implements TagFunction, IntSupplier { public static final HexId32 NONE = new HexId32(0); public static final HexId32 SELF = new HexId32(-1); public static BiConsumer TAG = (parent, id) -> parent.string(id.toString()); @@ -61,7 +61,7 @@ public boolean equals(Object obj) { } @Override - public void appendHTMLTag(Tag parent) { + public void acceptTag(Tag parent) { TAG.accept(parent, this); } diff --git a/src/main/java/dev/latvian/apps/webutils/data/HexId64.java b/src/main/java/dev/latvian/apps/webutils/data/HexId64.java index 8e89bdd..da2274a 100644 --- a/src/main/java/dev/latvian/apps/webutils/data/HexId64.java +++ b/src/main/java/dev/latvian/apps/webutils/data/HexId64.java @@ -1,12 +1,12 @@ package dev.latvian.apps.webutils.data; import dev.latvian.apps.webutils.html.Tag; -import dev.latvian.apps.webutils.html.TagConvertible; +import dev.latvian.apps.webutils.html.TagFunction; import java.util.function.BiConsumer; import java.util.function.LongSupplier; -public class HexId64 implements TagConvertible, LongSupplier { +public class HexId64 implements TagFunction, LongSupplier { public static final HexId64 NONE = new HexId64(0L); public static final HexId64 SELF = new HexId64(-1L); public static BiConsumer TAG = (parent, id) -> parent.string(id.toString()); @@ -61,7 +61,7 @@ public boolean equals(Object obj) { } @Override - public void appendHTMLTag(Tag parent) { + public void acceptTag(Tag parent) { TAG.accept(parent, this); } diff --git a/src/main/java/dev/latvian/apps/webutils/html/HTMLTable.java b/src/main/java/dev/latvian/apps/webutils/html/HTMLTable.java new file mode 100644 index 0000000..ed983d6 --- /dev/null +++ b/src/main/java/dev/latvian/apps/webutils/html/HTMLTable.java @@ -0,0 +1,175 @@ +package dev.latvian.apps.webutils.html; + +import java.util.ArrayList; +import java.util.List; + +public class HTMLTable implements TagFunction { + public static class Col { + public final HTMLTable table; + public final int x; + private Cell label; + private TagFunction applyToCell = null; + + private Col(HTMLTable table, int x) { + this.table = table; + this.x = x; + } + + public Col applyToCell(TagFunction applyToCell) { + this.applyToCell = applyToCell; + return this; + } + + public Col set(int y, TagFunction value) { + table.set(x, y, value); + return this; + } + } + + public static class Row { + public final HTMLTable table; + public final int y; + public final List cells; + private TagFunction apply = null; + private TagFunction applyToCell = null; + + public Row(HTMLTable table, int y) { + this.table = table; + this.y = y; + this.cells = new ArrayList<>(2); + } + + public Row apply(TagFunction apply) { + this.apply = apply; + return this; + } + + public Row applyToCell(TagFunction applyToCell) { + this.applyToCell = applyToCell; + return this; + } + + public Row set(int x, TagFunction value) { + cells.get(x).set(value); + return this; + } + } + + public static class Cell { + public final Col col; + public final Row row; + private TagFunction value = TagFunction.IDENTITY; + + private Cell(Col col, Row row) { + this.col = col; + this.row = row; + } + + public Cell set(TagFunction value) { + this.value = value; + return this; + } + } + + public final Row headRow; + private final List cols; + private final List rows; + + public HTMLTable() { + this.headRow = new Row(this, -1); + this.cols = new ArrayList<>(2); + this.rows = new ArrayList<>(2); + } + + public HTMLTable(TagFunction... labels) { + this(); + + for (var label : labels) { + addCol(label); + } + } + + public HTMLTable(String... labels) { + this(); + + for (var label : labels) { + addCol(t -> t.string(label)); + } + } + + public Col col(int x) { + return cols.get(x); + } + + public int cols() { + return cols.size(); + } + + public Row row(int y) { + return rows.get(y); + } + + public int rows() { + return rows.size(); + } + + public Col addCol(TagFunction label) { + var col = new Col(this, cols.size()); + cols.add(col); + + col.label = new Cell(col, headRow); + headRow.cells.add(col.label); + col.label.value = label; + + for (var row : rows) { + row.cells.add(new Cell(col, row)); + } + + return col; + } + + public Row addRow() { + var row = new Row(this, rows.size()); + rows.add(row); + + for (var col : cols) { + row.cells.add(new Cell(col, row)); + } + + return row; + } + + public void addRow(TagFunction... h) { + var r = addRow(); + + for (int i = 0; i < h.length; i++) { + r.set(i, h[i]); + } + } + + public HTMLTable set(int x, int y, TagFunction value) { + rows.get(y).set(x, value); + return this; + } + + @Override + public void acceptTag(Tag tag) { + var table = tag.table(); + var theadTag = table.thead(); + var headTag = theadTag.tr().add(headRow.apply); + + for (var cell : headRow.cells) { + headTag.th().add(cell.value).add(headRow.applyToCell).add(cell.col.applyToCell); + } + + var tbodyTag = table.tbody(); + + for (var row : rows) { + var rowTag = tbodyTag.tr().add(row.apply); + + for (var cell : row.cells) { + rowTag.td().add(cell.value).add(row.applyToCell).add(cell.col.applyToCell); + } + } + } +} diff --git a/src/main/java/dev/latvian/apps/webutils/html/Tag.java b/src/main/java/dev/latvian/apps/webutils/html/Tag.java index 08da809..7453389 100644 --- a/src/main/java/dev/latvian/apps/webutils/html/Tag.java +++ b/src/main/java/dev/latvian/apps/webutils/html/Tag.java @@ -10,9 +10,9 @@ import java.util.regex.Pattern; @SuppressWarnings({"unused", "UnusedReturnValue"}) -public interface Tag extends TagConvertible { +public interface Tag extends TagFunction { @Override - default void appendHTMLTag(Tag parent) { + default void acceptTag(Tag parent) { parent.add(this); } @@ -69,8 +69,11 @@ default Tag getChild(int index) { throw new IllegalStateException("This tag type does not support children tags"); } - default Tag add(TagConvertible tag) { - tag.appendHTMLTag(this); + default Tag add(@Nullable TagFunction function) { + if (function != null) { + function.acceptTag(this); + } + return this; } diff --git a/src/main/java/dev/latvian/apps/webutils/html/TagConvertible.java b/src/main/java/dev/latvian/apps/webutils/html/TagConvertible.java deleted file mode 100644 index 8777b5b..0000000 --- a/src/main/java/dev/latvian/apps/webutils/html/TagConvertible.java +++ /dev/null @@ -1,5 +0,0 @@ -package dev.latvian.apps.webutils.html; - -public interface TagConvertible { - void appendHTMLTag(Tag parent); -} diff --git a/src/main/java/dev/latvian/apps/webutils/html/TagFunction.java b/src/main/java/dev/latvian/apps/webutils/html/TagFunction.java new file mode 100644 index 0000000..120ecca --- /dev/null +++ b/src/main/java/dev/latvian/apps/webutils/html/TagFunction.java @@ -0,0 +1,9 @@ +package dev.latvian.apps.webutils.html; + +@FunctionalInterface +public interface TagFunction { + TagFunction IDENTITY = t -> { + }; + + void acceptTag(Tag tag); +} diff --git a/src/main/java/dev/latvian/apps/webutils/html/TagResponseContent.java b/src/main/java/dev/latvian/apps/webutils/html/TagResponseContent.java new file mode 100644 index 0000000..3320e6f --- /dev/null +++ b/src/main/java/dev/latvian/apps/webutils/html/TagResponseContent.java @@ -0,0 +1,18 @@ +package dev.latvian.apps.webutils.html; + +import dev.latvian.apps.tinyserver.content.MimeType; +import dev.latvian.apps.tinyserver.content.ResponseContent; + +import java.io.IOException; +import java.io.OutputStream; + +public record TagResponseContent(Tag tag, boolean header) implements ResponseContent { + @Override + public String type() { + return MimeType.HTML; + } + + @Override + public void write(OutputStream outputStream) throws IOException { + } +} diff --git a/src/main/java/dev/latvian/apps/webutils/html/UserError.java b/src/main/java/dev/latvian/apps/webutils/html/UserError.java deleted file mode 100644 index b00f800..0000000 --- a/src/main/java/dev/latvian/apps/webutils/html/UserError.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.latvian.apps.webutils.html; - -import dev.latvian.apps.tinyserver.http.response.HTTPStatus; -import org.jetbrains.annotations.Nullable; - -public class UserError extends RuntimeException { - public final HTTPStatus status; - public final Tag displayMessage; - - public UserError(HTTPStatus status, String message, @Nullable Tag displayMessage) { - super(message); - this.status = status; - this.displayMessage = displayMessage; - } - - public UserError(HTTPStatus status, String message) { - this(status, message, null); - } -} diff --git a/src/test/java/dev/latvian/apps/webutils/test/TableTest.java b/src/test/java/dev/latvian/apps/webutils/test/TableTest.java new file mode 100644 index 0000000..cacbef3 --- /dev/null +++ b/src/test/java/dev/latvian/apps/webutils/test/TableTest.java @@ -0,0 +1,22 @@ +package dev.latvian.apps.webutils.test; + +import dev.latvian.apps.ansi.ANSI; +import dev.latvian.apps.ansi.log.Log; +import dev.latvian.apps.webutils.html.HTMLTable; +import dev.latvian.apps.webutils.html.PairedTag; +import dev.latvian.apps.webutils.html.TagANSI; +import org.junit.jupiter.api.Test; + +public class TableTest { + @Test + public void table() { + var table = new HTMLTable("Col 1", "Col 2", "Col 3"); + + for (int i = 0; i < 10; i++) { + var j = i; + table.addRow(t -> t.string("Row " + j), t -> t.string("Value " + j), t -> t.string("Another value " + j)); + } + + Log.info(ANSI.empty().append(ANSI.LINE).append(TagANSI.of(new PairedTag("").add(table), true))); + } +}