aboutsummaryrefslogtreecommitdiff
path: root/internal/game/table.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/table.go')
-rw-r--r--internal/game/table.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/internal/game/table.go b/internal/game/table.go
new file mode 100644
index 0000000..e3dad97
--- /dev/null
+++ b/internal/game/table.go
@@ -0,0 +1,100 @@
+package game
+
+import (
+ "fmt"
+ "strings"
+)
+
+type tableGlyphs struct {
+ topLeft, topSep, topRight rune
+ side, colSep rune
+ sepLeft, sepCross, sepRight rune
+ botLeft, botSep, botRight rune
+ fillH, fillHSep rune
+}
+
+func tableGlyphSet(unicode bool) tableGlyphs {
+ if unicode {
+ return tableGlyphs{
+ topLeft: '╔', topSep: '╤', topRight: '╗', side: '║', colSep: '│',
+ sepLeft: '╟', sepCross: '┼', sepRight: '╢',
+ botLeft: '╚', botSep: '╧', botRight: '╝', fillH: '═', fillHSep: '─',
+ }
+ }
+ return tableGlyphs{
+ topLeft: '+', topSep: '+', topRight: '+', side: '|', colSep: '|',
+ sepLeft: '+', sepCross: '+', sepRight: '+',
+ botLeft: '+', botSep: '+', botRight: '+', fillH: '-', fillHSep: '-',
+ }
+}
+
+type Table struct {
+ Columns []string
+ Rows [][]string
+}
+
+func (t *Table) Render(unicode bool) []string {
+ g := tableGlyphSet(unicode)
+
+ nCols := len(t.Columns)
+ if nCols == 0 {
+ return nil
+ }
+
+ colWidths := make([]int, nCols)
+ for i, h := range t.Columns {
+ colWidths[i] = len(h)
+ }
+ for _, row := range t.Rows {
+ for i, cell := range row {
+ if i >= nCols {
+ break
+ }
+ if len(cell) > colWidths[i] {
+ colWidths[i] = len(cell)
+ }
+ }
+ }
+
+ makeSep := func(left, cross, right rune, fill rune) string {
+ var b strings.Builder
+ b.WriteRune(left)
+ for i := 0; i < nCols; i++ {
+ if i > 0 {
+ b.WriteRune(cross)
+ }
+ b.WriteString(strings.Repeat(string(fill), colWidths[i]+2))
+ }
+ b.WriteRune(right)
+ return b.String()
+ }
+
+ makeRow := func(cells []string) string {
+ var b strings.Builder
+ b.WriteRune(g.side)
+ for i := 0; i < nCols; i++ {
+ if i > 0 {
+ b.WriteRune(g.colSep)
+ }
+ cell := ""
+ if i < len(cells) {
+ cell = cells[i]
+ }
+ b.WriteString(fmt.Sprintf(" %-*s ", colWidths[i], cell))
+ }
+ b.WriteRune(g.side)
+ return b.String()
+ }
+
+ var out []string
+
+ out = append(out, makeSep(g.topLeft, g.topSep, g.topRight, g.fillH))
+ out = append(out, makeRow(t.Columns))
+ out = append(out, makeSep(g.sepLeft, g.sepCross, g.sepRight, g.fillHSep))
+ for _, row := range t.Rows {
+ out = append(out, makeRow(row))
+ }
+ out = append(out, makeSep(g.botLeft, g.botSep, g.botRight, g.fillH))
+
+ return out
+}