feat(io): semantic styled-text model (Style, Span, StyledText)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package thb.jeanluc.adventure.io.text;
|
||||
|
||||
/** A run of text carrying a single semantic {@link Style}. */
|
||||
public record Span(String text, Style style) {
|
||||
public Span {
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("text must not be null");
|
||||
}
|
||||
if (style == null) {
|
||||
throw new IllegalArgumentException("style must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package thb.jeanluc.adventure.io.text;
|
||||
|
||||
/** Semantic output roles. Renderers map each role to concrete colours/attributes. */
|
||||
public enum Style { PLAIN, HEADING, ITEM, NPC, EXIT, DANGER, DIM }
|
||||
@@ -0,0 +1,59 @@
|
||||
package thb.jeanluc.adventure.io.text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** An ordered, immutable list of styled {@link Span}s. Built via {@link Builder}. */
|
||||
public final class StyledText {
|
||||
|
||||
private final List<Span> spans;
|
||||
|
||||
private StyledText(List<Span> spans) {
|
||||
this.spans = List.copyOf(spans);
|
||||
}
|
||||
|
||||
/** @return the spans in order (unmodifiable). */
|
||||
public List<Span> spans() {
|
||||
return spans;
|
||||
}
|
||||
|
||||
/** @return all span text concatenated, without any styling. */
|
||||
public String plainText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Span s : spans) {
|
||||
sb.append(s.text());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/** @return a styled text of a single {@link Style#PLAIN} span. */
|
||||
public static StyledText of(String s) {
|
||||
return new StyledText(List.of(new Span(s, Style.PLAIN)));
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Fluent builder; one method per {@link Style} role. */
|
||||
public static final class Builder {
|
||||
private final List<Span> spans = new ArrayList<>();
|
||||
|
||||
private Builder add(String text, Style style) {
|
||||
spans.add(new Span(text, style));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder plain(String s) { return add(s, Style.PLAIN); }
|
||||
public Builder heading(String s) { return add(s, Style.HEADING); }
|
||||
public Builder item(String s) { return add(s, Style.ITEM); }
|
||||
public Builder npc(String s) { return add(s, Style.NPC); }
|
||||
public Builder exit(String s) { return add(s, Style.EXIT); }
|
||||
public Builder danger(String s) { return add(s, Style.DANGER); }
|
||||
public Builder dim(String s) { return add(s, Style.DIM); }
|
||||
|
||||
public StyledText build() {
|
||||
return new StyledText(spans);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user