Documentation
¶
Overview ¶
Package output provides a reusable Go library for CLI applications offering consistent output formatting across 16 formats (Table, JSON, CSV, TSV, Markdown, XML, YAML, HTML, Tree, D2, Mermaid, DOT, JSONL, AsciiDoc, TOML, PlantUML) with type-safe enum-based configuration and a Shape capability matrix.
Quick Start ¶
Use Table as the single source of truth for tabular data:
data := output.NewTable([]string{"Name", "Status"})
data.AddRow([]string{"Project A", "Active"})
data.Footer = []string{"Total", "1"}
Render to any supported format:
var buf bytes.Buffer
_ = output.RenderTable(data, output.FormatMarkdown, output.RenderOptions{Writer: &buf})
Architecture ¶
The library uses a multi-module workspace where each format family is an independent Go module. Users import only the formats they need:
import "github.com/larsartmann/go-output" // core + Markdown + Tree import "github.com/larsartmann/go-output/table" // terminal tables (optional) import "github.com/larsartmann/go-output/serialization" // JSON + YAML + TOML + JSONL (optional) import "github.com/larsartmann/go-output/delimited" // CSV + TSV (optional) import "github.com/larsartmann/go-output/markup" // XML + HTML + AsciiDoc (optional) import "github.com/larsartmann/go-output/d2" // D2 diagrams (optional) import "github.com/larsartmann/go-output/graph" // DOT + Mermaid (optional) import "github.com/larsartmann/go-output/plantuml" // PlantUML diagrams (optional)
The root module has ZERO imports from sub-modules, ensuring users get zero transitive dependencies from formats they don't use.
Index ¶
- Variables
- func AddTreeNodes(a NodeEdgeAppender, node *TreeNode, parentID string, idFunc TreeNodeIDFunc, ...)
- func ContainsEnum[T comparable](values []T, v T) bool
- func DefaultGraphNodeLabel(header, cell string) string
- func EnumAllowedStrings[T any](values []T, toString func(T) string) []string
- func EnumAllowedValues[T StringEnum](values []T) []string
- func IsCI() bool
- func IsNoColor() bool
- func MarshalJSONIndent(v any, prefix, indent string) ([]byte, error)
- func NewBrandedID[Brand any](value string) id.ID[Brand, string]
- func ParseEnum[T comparable](values []T, s string, toString func(T) string) (T, error)
- func RegisterFormatShapes(format Format, shapes ...Shape)
- func RegisterTableMarshaler(format Format, renderer TableMarshaler)
- func RegisterUnknownRenderer(format Format, renderer UnknownRenderer)
- func RenderTable(data *Table, format Format, opts RenderOptions) error
- func RenderUnknown(data any, format Format, opts RenderOptions) error
- func TreeToRenderer[R, ID any](newRenderer func() R, addNodes func(R, *TreeNode, ID), root *TreeNode) R
- type BrandedID
- type ColorMode
- type D2NodeID
- type D2NodeIDBrand
- type D2NodeLabel
- type D2NodeLabelBrand
- type Direction
- type EdgeStyle
- type Format
- type Graph
- type GraphBuilder
- func (m *GraphBuilder) AddEdge(edge GraphEdge)
- func (m *GraphBuilder) AddNode(node GraphNode)
- func (m *GraphBuilder) AddRowEdges(data *Table)
- func (m *GraphBuilder) Build() Graph
- func (m *GraphBuilder) DedupEdges()
- func (m *GraphBuilder) Edges() []GraphEdge
- func (m *GraphBuilder) Nodes() []GraphNode
- func (m *GraphBuilder) SetEdges(edges []GraphEdge)
- func (m *GraphBuilder) SetNodes(nodes []GraphNode)
- func (m *GraphBuilder) SetNodesFromTable(data *Table, modifyNode func(i int, n *GraphNode))
- type GraphEdge
- type GraphNode
- type GraphNodeID
- type GraphNodeIDBrand
- type GraphNodeLabel
- type GraphNodeLabelBrand
- type GraphNodeLabelFunc
- type GraphRenderer
- type InvalidColorModeError
- type InvalidFormatError
- type InvalidLineStyleError
- type InvalidNodeShapeError
- type InvalidShapeError
- type LineStyle
- type NodeEdgeAppender
- type NodeShape
- type NodeStyle
- type ParseError
- type RenderOptions
- type Renderer
- type RowEdge
- type Shape
- type StreamingRenderer
- type StringEnum
- type Table
- func (d *Table) AddRow(row []string)
- func (d *Table) AddRowChecked(row []string) error
- func (d *Table) ColCount() int
- func (d *Table) CreateRowEdges() []RowEdge
- func (d *Table) GetFooter() []string
- func (d *Table) GetHeaders() []string
- func (d *Table) GetRows() [][]string
- func (d *Table) HasFooter() bool
- func (d *Table) RowCount() int
- func (d *Table) SetFooter(footer []string)
- func (d *Table) ToMapSlice() []map[string]string
- func (d *Table) Validate() error
- type TableBuilder
- type TableMarshaler
- type TableRenderer
- type TableStore
- type TableToGraphOption
- type TreeBuilder
- type TreeNode
- type TreeNodeID
- type TreeNodeIDBrand
- type TreeNodeIDFunc
- type TreeNodeLabel
- type TreeNodeLabelBrand
- type TreeRenderer
- type UnknownRenderer
- type UnsupportedFormatError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var AllDirections = []Direction{DirectionDown, DirectionUp, DirectionLeft, DirectionRight}
var AllFormats = []Format{ FormatTable, FormatJSON, FormatCSV, FormatTSV, FormatMarkdown, FormatXML, FormatD2, FormatYAML, FormatHTML, FormatTree, FormatMermaid, FormatDOT, FormatJSONL, FormatAsciiDoc, FormatTOML, FormatPlantUML, }
AllFormats contains all valid output format values. Use this for testing AllowedValues or generating help text.
var AllLineStyles = []LineStyle{ LineStyleSolid, LineStyleDashed, LineStyleDotted, }
var AllShapes = []Shape{ ShapeTable, ShapeTree, ShapeGraph, }
AllShapes contains all valid data shape values.
var CIEnvVars = []string{
"CI",
"GITHUB_ACTIONS",
"GITLAB_CI",
"JENKINS_URL",
"BUILDKITE",
}
CIEnvVars are the environment variables that indicate execution inside a common CI provider. Exported so tests and downstream code can keep their own list of "known suppressors" aligned with this one.
Functions ¶
func AddTreeNodes ¶
func AddTreeNodes( a NodeEdgeAppender, node *TreeNode, parentID string, idFunc TreeNodeIDFunc, shape NodeShape, )
AddTreeNodes recursively adds tree nodes and edges to the provided appender.
func ContainsEnum ¶ added in v0.18.0
func ContainsEnum[T comparable](values []T, v T) bool
ContainsEnum checks if a value is in the list of allowed values.
func DefaultGraphNodeLabel ¶
DefaultGraphNodeLabel returns a label in the format "header: cell".
func EnumAllowedStrings ¶ added in v0.18.0
EnumAllowedStrings returns the string representations of all enum values.
func EnumAllowedValues ¶ added in v0.18.0
func EnumAllowedValues[T StringEnum](values []T) []string
EnumAllowedValues returns the string representations of all enum values for types that implement the StringEnum interface.
func IsCI ¶ added in v0.18.0
func IsCI() bool
IsCI reports whether the process appears to be running inside a CI provider by checking the well-known CI environment variables.
func IsNoColor ¶ added in v0.18.0
func IsNoColor() bool
IsNoColor reports whether color output should be suppressed per the NO_COLOR convention (https://no-color.org) or a TERM=dumb terminal.
func MarshalJSONIndent ¶
MarshalJSONIndent encodes v to indented JSON.
func NewBrandedID ¶
NewBrandedID creates a new branded ID from a string value.
func ParseEnum ¶ added in v0.18.0
func ParseEnum[T comparable](values []T, s string, toString func(T) string) (T, error)
ParseEnum parses a string into an enum value, returning an error if invalid.
func RegisterFormatShapes ¶ added in v0.7.0
RegisterFormatShapes registers the data shapes a format supports. Sub-modules call this from their init() to declare capabilities.
func RegisterTableMarshaler ¶ added in v0.30.0
func RegisterTableMarshaler(format Format, renderer TableMarshaler)
RegisterTableMarshaler registers a renderer for a format. Sub-modules call this from their init() to enable RenderTable dispatch.
func RegisterUnknownRenderer ¶ added in v0.30.0
func RegisterUnknownRenderer(format Format, renderer UnknownRenderer)
RegisterUnknownRenderer registers a renderer for arbitrary (non-Table) data. Sub-modules call this from their init() to enable RenderUnknown dispatch.
func RenderTable ¶ added in v0.30.0
func RenderTable(data *Table, format Format, opts RenderOptions) error
RenderTable renders Table in the given format and writes to w (or os.Stdout). It supports all registered formats when respective sub-modules are imported. With all sub-modules imported, all 16 formats are available: table, json, csv, tsv, markdown, xml, d2, yaml, html, tree, mermaid, dot, jsonl, asciidoc, toml, plantuml.
func RenderUnknown ¶ added in v0.30.0
func RenderUnknown(data any, format Format, opts RenderOptions) error
RenderUnknown renders arbitrary data in the given format and writes to w (or os.Stdout). Supports formats that registered an UnknownRenderer (typically JSON, YAML, TOML). Returns UnsupportedFormatError if no renderer is registered for the format.
func TreeToRenderer ¶ added in v0.19.0
func TreeToRenderer[R, ID any]( newRenderer func() R, addNodes func(R, *TreeNode, ID), root *TreeNode, ) R
TreeToRenderer runs the standard tree entrypoint prelude used by every sub-module's public XFromTree: instantiate the renderer, skip population when root is nil, otherwise call the renderer-specific addNodes with the given zero parent ID (every XFromTree starts a fresh subtree). Centralising this in root means each sub-module's entrypoint is a single line and the constructor + nil-check + populate prelude lives in exactly one place.
The ID type is renderer-specific: graph and plantuml use TreeNodeID; d2 and mermaid use plain string. Both shapes share this single generic helper.
Types ¶
type BrandedID ¶
BrandedID re-export for backward compatibility. Use id.ID[Brand, string] for new code.
type ColorMode ¶
type ColorMode string
ColorMode controls terminal color output.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
fmt.Println(output.ColorModeAuto.ShouldColor())
fmt.Println(output.ColorModeNever.ShouldColor())
}
Output: false false
const ( ColorModeAuto ColorMode = "auto" ColorModeAlways ColorMode = "always" ColorModeNever ColorMode = "never" )
Terminal color output modes.
func ParseColorMode ¶
ParseColorMode converts a string to ColorMode, returning an error if invalid.
func (ColorMode) AllowedValues ¶
AllowedValues returns all valid color mode values.
func (ColorMode) ShouldColor ¶
ShouldColor returns true if colors should be enabled.
type D2NodeID ¶
type D2NodeID = id.ID[D2NodeIDBrand, string]
D2NodeID is a branded identifier for D2 diagram nodes. Canonical import path: github.com/larsartmann/go-output (root). The d2 module re-exports this as d2.D2NodeID for convenience.
type D2NodeIDBrand ¶
type D2NodeIDBrand struct{}
D2NodeIDBrand is the brand type for D2 node IDs. Lives in root so the type alias D2NodeID is visible to both root and d2/ callers without a circular import. Split-brain finding m6: root is the canonical home; d2.D2NodeID is a convenience re-export (type alias), not a second definition.
type D2NodeLabel ¶
type D2NodeLabel = id.ID[D2NodeLabelBrand, string]
D2NodeLabel is a branded identifier for D2 diagram node labels. Canonical import path: github.com/larsartmann/go-output (root). The d2 module re-exports this as d2.D2NodeLabel for convenience.
type D2NodeLabelBrand ¶
type D2NodeLabelBrand struct{}
D2NodeLabelBrand is the brand type for D2 node labels. See D2NodeIDBrand for why brand types live in root rather than d2/.
type Direction ¶ added in v0.13.0
type Direction string
Direction represents a canonical layout direction for diagrams. It bridges D2 vocabulary ("down"/"right") and DOT vocabulary ("TB"/"LR") through a single canonical type.
func (Direction) ToD2Direction ¶ added in v0.13.0
ToD2Direction converts Direction to D2's direction string. D2 uses "" for default (down), "right", "left", "up".
Returns a string (not d2.Direction) because root cannot import the d2/ sub-module (Core Invariant). The d2/ module's own D2Direction type is a separate type for D2-specific APIs; use output.Direction for cross-format portability and convert at the d2/ call site.
type EdgeStyle ¶
type EdgeStyle struct {
// Color is the edge line color.
Color string
// Line is the line style (solid, dashed, dotted).
Line LineStyle
}
EdgeStyle represents styling attributes for an edge.
type Format ¶
type Format string
Format represents the available output format options for CLI applications.
const ( FormatTable Format = "table" FormatJSON Format = "json" FormatCSV Format = "csv" FormatTSV Format = "tsv" FormatMarkdown Format = "markdown" FormatXML Format = "xml" FormatD2 Format = "d2" FormatYAML Format = "yaml" FormatHTML Format = "html" FormatTree Format = "tree" FormatMermaid Format = "mermaid" FormatDOT Format = "dot" FormatJSONL Format = "jsonl" FormatAsciiDoc Format = "asciidoc" FormatTOML Format = "toml" FormatPlantUML Format = "plantuml" )
Output format constants.
func FormatsForShape ¶ added in v0.5.0
FormatsForShape returns all formats that support the given data shape.
func ParseFormat ¶
ParseFormat converts a string to Format, returning an error if invalid.
Example ¶
package main
import (
"fmt"
"os"
"github.com/larsartmann/go-output"
)
func main() {
f, err := output.ParseFormat("json")
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
fmt.Println(f)
}
Output: json
func RegisteredTableMarshalFormats ¶ added in v0.30.0
func RegisteredTableMarshalFormats() []Format
RegisteredTableMarshalFormats returns all formats with registered TableMarshalers.
func RegisteredUnknownFormats ¶ added in v0.30.0
func RegisteredUnknownFormats() []Format
RegisteredUnknownFormats returns all formats with registered UnknownRenderers.
func (Format) AllowedValues ¶
AllowedValues returns all valid output format values for CLI help text.
func (Format) IsValid ¶
IsValid returns true if the format is a valid Format value.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
fmt.Println(output.FormatCSV.IsValid())
fmt.Println(output.Format("unknown").IsValid())
}
Output: true false
type Graph ¶ added in v0.30.0
type Graph struct {
// contains filtered or unexported fields
}
Graph is an immutable snapshot of graph data — the frozen result of GraphBuilder.Build(). It is safe for concurrent access and can be passed to multiple renderers (DOT, Mermaid, D2, PlantUML) without copying or locking.
func TableToGraph ¶ added in v0.30.0
func TableToGraph(data *Table, opts ...TableToGraphOption) Graph
TableToGraph converts a Table into a Graph by creating one node per row and connecting consecutive rows with directed edges. Each node is labeled with all cell values from its row. This is a pure projection — the input Table is not modified.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
tbl := output.NewTableBuilder().
SetHeaders("Step").
AddRow("Fetch").
AddRow("Build").
AddRow("Deploy").
Build()
g := output.TableToGraph(tbl)
fmt.Printf("%d nodes\n", len(g.Nodes()))
}
Output:
type GraphBuilder ¶ added in v0.30.0
type GraphBuilder struct {
// contains filtered or unexported fields
}
GraphBuilder contains shared fields and methods for graph renderers.
D2 does not use this mixin because it has richer domain-specific types (D2Node, D2Edge with classes, SQL tables, shapes, arrow types, etc.) that do not map to the simpler GraphNode/GraphEdge model.
func NewGraphBuilder ¶ added in v0.30.0
func NewGraphBuilder() GraphBuilder
NewGraphBuilder creates a new GraphBuilder with initialized slices.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
b := output.NewGraphBuilder()
b.AddNode(*output.NewGraphNode("a", "Alpha"))
b.AddNode(*output.NewGraphNode("b", "Beta"))
b.AddEdge(*output.NewGraphEdge("a", "b"))
g := b.Build()
fmt.Printf("%d nodes, %d edges\n", len(g.Nodes()), len(g.Edges()))
}
Output:
func (*GraphBuilder) AddEdge ¶ added in v0.30.0
func (m *GraphBuilder) AddEdge(edge GraphEdge)
AddEdge appends an edge to the graph.
func (*GraphBuilder) AddNode ¶ added in v0.30.0
func (m *GraphBuilder) AddNode(node GraphNode)
AddNode appends a node to the graph.
func (*GraphBuilder) AddRowEdges ¶ added in v0.30.0
func (m *GraphBuilder) AddRowEdges(data *Table)
AddRowEdges adds edges from data.CreateRowEdges() to the graph.
func (*GraphBuilder) Build ¶ added in v0.30.0
func (m *GraphBuilder) Build() Graph
Build freezes the builder's state into an immutable Graph. After Build, the Graph is a snapshot — further mutations to the builder do not affect it.
func (*GraphBuilder) DedupEdges ¶ added in v0.30.0
func (m *GraphBuilder) DedupEdges()
DedupEdges removes duplicate edges in-place. Two edges are considered duplicates if they share the same From and To node IDs. The first occurrence is kept; subsequent duplicates are silently discarded. Edges with different labels between the same node pair are also considered duplicates — if you need parallel edges, do not call this method.
func (*GraphBuilder) Edges ¶ added in v0.30.0
func (m *GraphBuilder) Edges() []GraphEdge
Edges returns the graph edges.
func (*GraphBuilder) Nodes ¶ added in v0.30.0
func (m *GraphBuilder) Nodes() []GraphNode
Nodes returns the graph nodes.
func (*GraphBuilder) SetEdges ¶ added in v0.30.0
func (m *GraphBuilder) SetEdges(edges []GraphEdge)
SetEdges sets the graph edges.
func (*GraphBuilder) SetNodes ¶ added in v0.30.0
func (m *GraphBuilder) SetNodes(nodes []GraphNode)
SetNodes sets the graph nodes.
func (*GraphBuilder) SetNodesFromTable ¶ added in v0.30.0
func (m *GraphBuilder) SetNodesFromTable( data *Table, modifyNode func(i int, n *GraphNode), )
SetNodesFromTable creates nodes from Table, applies per-node modifications, adds them to the graph, and adds row edges.
type GraphEdge ¶
type GraphEdge struct {
// From is the source node ID.
From GraphNodeID
// To is the target node ID.
To GraphNodeID
// Label is the optional display text on the edge.
Label GraphNodeLabel
// Style contains optional visual styling attributes.
Style EdgeStyle
}
GraphEdge represents an edge between two nodes.
func NewGraphEdge ¶
NewGraphEdge creates a new GraphEdge.
type GraphNode ¶
type GraphNode struct {
// ID is the unique identifier for the node.
ID GraphNodeID
// Label is the display text for the node.
Label GraphNodeLabel
// Shape defines the visual shape (box, ellipse, diamond, etc.).
Shape NodeShape
// Style contains optional visual styling attributes.
Style NodeStyle
// Metadata holds arbitrary key-value pairs for custom data.
Metadata map[string]string
}
GraphNode represents a node in a graph.
func NewGraphNode ¶
NewGraphNode creates a new GraphNode.
func NodesFromTable ¶ added in v0.30.0
func NodesFromTable(data *Table, labelFn GraphNodeLabelFunc) []GraphNode
NodesFromTable creates GraphNodes from Table using the provided label function.
type GraphNodeID ¶
type GraphNodeID = id.ID[GraphNodeIDBrand, string]
GraphNodeID is a branded identifier for graph nodes.
type GraphNodeIDBrand ¶
type GraphNodeIDBrand struct{}
GraphNodeIDBrand is the brand type for graph node IDs.
type GraphNodeLabel ¶
type GraphNodeLabel = id.ID[GraphNodeLabelBrand, string]
GraphNodeLabel is a branded identifier for graph node labels.
type GraphNodeLabelBrand ¶
type GraphNodeLabelBrand struct{}
GraphNodeLabelBrand is the brand type for graph node labels.
type GraphNodeLabelFunc ¶
GraphNodeLabelFunc is a function that formats a cell value with its header into a label.
type GraphRenderer ¶
type GraphRenderer interface {
Renderer
// SetNodes sets the graph nodes.
SetNodes(nodes []GraphNode)
// SetEdges sets the graph edges.
SetEdges(edges []GraphEdge)
}
GraphRenderer defines the interface for graph format renderers.
type InvalidColorModeError ¶ added in v0.5.0
type InvalidColorModeError struct {
Value string
}
InvalidColorModeError is returned when an invalid color mode is provided.
func (*InvalidColorModeError) Error ¶ added in v0.5.0
func (e *InvalidColorModeError) Error() string
Error returns a descriptive error message for the invalid color mode.
type InvalidFormatError ¶
InvalidFormatError represents an invalid format error.
func (*InvalidFormatError) Error ¶
func (e *InvalidFormatError) Error() string
Error returns a descriptive error message including allowed values.
type InvalidLineStyleError ¶ added in v0.18.0
InvalidLineStyleError is returned when an invalid line style is provided.
func (*InvalidLineStyleError) Error ¶ added in v0.18.0
func (e *InvalidLineStyleError) Error() string
Error returns a descriptive error message for the invalid line style.
type InvalidNodeShapeError ¶ added in v0.13.0
type InvalidNodeShapeError struct {
Value string
}
InvalidNodeShapeError is returned when an invalid graph shape is provided.
func (*InvalidNodeShapeError) Error ¶ added in v0.13.0
func (e *InvalidNodeShapeError) Error() string
Error returns a descriptive error message for the invalid graph shape.
type InvalidShapeError ¶ added in v0.5.0
InvalidShapeError is returned when an invalid data shape is provided.
func (*InvalidShapeError) Error ¶ added in v0.5.0
func (e *InvalidShapeError) Error() string
Error returns a descriptive error message for the invalid shape.
type LineStyle ¶ added in v0.13.0
type LineStyle string
LineStyle represents the visual style of a line (edge).
func ParseLineStyle ¶ added in v0.18.0
ParseLineStyle converts a string to LineStyle, returning an error if invalid.
func (LineStyle) AllowedValues ¶ added in v0.18.0
AllowedValues returns all valid line style values for CLI help text.
type NodeEdgeAppender ¶ added in v0.7.0
NodeEdgeAppender is implemented by types that can add nodes and edges.
type NodeShape ¶ added in v0.13.0
type NodeShape string
NodeShape represents the shape of a graph node.
const ( NodeShapeBox NodeShape = "box" NodeShapeEllipse NodeShape = "ellipse" NodeShapeDiamond NodeShape = "diamond" NodeShapeCircle NodeShape = "circle" NodeShapeCylinder NodeShape = "cylinder" NodeShapeHexagon NodeShape = "hexagon" NodeShapeParallelogram NodeShape = "parallelogram" )
NodeShape constants define the available shapes for graph nodes.
func ParseNodeShape ¶ added in v0.13.0
ParseNodeShape converts a string to NodeShape, returning an error if invalid.
func (NodeShape) AllowedValues ¶ added in v0.13.0
AllowedValues returns all valid graph shape values.
type NodeStyle ¶ added in v0.30.0
type NodeStyle struct {
// Fill is the background color (e.g., "#f9f9f9").
Fill string
// Stroke is the border color.
Stroke string
// FontColor is the text color.
FontColor string
// FontSize is the text size in points.
FontSize int
}
NodeStyle represents styling attributes for a graph node.
type ParseError ¶ added in v0.18.0
ParseError represents a parse error for enum types.
func (*ParseError) Error ¶ added in v0.18.0
func (e *ParseError) Error() string
Error returns a descriptive error message including the invalid value and allowed values.
type RenderOptions ¶ added in v0.5.0
type RenderOptions struct {
// Title is used as the document title for HTML output and as a header for Markdown.
Title string
// Writer overrides the default os.Stdout output destination.
Writer io.Writer
// ColorMode controls terminal color output. Defaults to ColorModeAuto.
ColorMode ColorMode
}
RenderOptions configures optional behavior for RenderTable.
type Renderer ¶
type Renderer interface {
// Render returns the formatted output as a string.
Render() (string, error)
}
Renderer defines the interface for output format renderers.
type RowEdge ¶
type RowEdge struct {
From GraphNodeID
To GraphNodeID
}
RowEdge represents a directed edge between two row identifiers.
type Shape ¶ added in v0.5.0
type Shape string
Shape represents a data shape that a format can render.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
fmt.Println(output.FormatCSV.Supports(output.ShapeTable))
fmt.Println(output.FormatCSV.Supports(output.ShapeTree))
}
Output: true false
const ( ShapeTable Shape = "table" // Tabular data with headers and rows ShapeTree Shape = "tree" // Hierarchical data with parent-child nodes ShapeGraph Shape = "graph" // Network data with nodes and edges )
Data shape constants for format capability classification.
func ParseShape ¶ added in v0.5.0
ParseShape converts a string to Shape, returning an error if invalid.
func (Shape) AllowedValues ¶ added in v0.5.0
AllowedValues returns all valid data shape values for CLI help text.
type StreamingRenderer ¶
type StreamingRenderer interface {
Renderer
// Stream writes the rendered output to an io.Writer in chunks.
Stream(w io.Writer) error
}
StreamingRenderer is an interface for renderers that support streaming output. This is useful for rendering large datasets without loading everything into memory.
Important: Not all implementations provide true streaming. The adapter returned by RendererAsWriter collects output before writing. Only StreamingHTMLRenderer (in the markup sub-module) provides genuine streaming behavior.
func RendererAsWriter ¶ added in v0.30.0
func RendererAsWriter(r Renderer) StreamingRenderer
RendererAsWriter wraps a standard Renderer to implement StreamingRenderer. The name is honest: it renders the full output via Render() then writes it to the writer in one shot — NOT true streaming. For genuine streaming, use StreamingHTMLRenderer (markup sub-module).
type StringEnum ¶ added in v0.18.0
type StringEnum interface {
String() string
}
StringEnum is an interface for string-based enum types.
type Table ¶ added in v0.30.0
type Table struct {
// Headers are the column header labels.
Headers []string
// Rows contains the data rows, each a slice of cell values.
Rows [][]string
// Tabular formats (CSV, TSV, Markdown, HTML, XML, AsciiDoc, Table) render it visually.
// Data formats (JSON, YAML, TOML, JSONL) and non-tabular formats skip it.
Footer []string
}
Table represents tabular data with headers, rows, and an optional footer.
func GraphToTable ¶ added in v0.30.0
GraphToTable converts a Graph into a Table with columns "ID" and "Label", one row per node. Edges are not represented in the table format. This is a pure projection — the input Graph is not modified.
func (*Table) AddRow ¶ added in v0.30.0
AddRow adds a row to the table data.
This method does NOT validate the row's column count. Use AddRowChecked to return an error, or call Validate() before rendering to surface mismatched rows. Existing callers that rely on silent acceptance are preserved; new code should prefer AddRowChecked for fail-fast behavior.
func (*Table) AddRowChecked ¶ added in v0.30.0
AddRowChecked adds a row to the table data and returns an error if the row's column count does not match the header count.
Returns nil if no headers are set, deferring validation to Validate(). Returns ErrColumnMismatch if the row length differs from len(Headers).
func (*Table) ColCount ¶ added in v0.30.0
ColCount returns the number of columns (based on headers).
func (*Table) CreateRowEdges ¶ added in v0.30.0
CreateRowEdges generates edge data connecting consecutive rows. Used by graph renderers to create edges between table rows.
func (*Table) GetFooter ¶ added in v0.30.0
GetFooter returns the footer row, or nil if none is set. Satisfies the table.FooterProvider optional interface.
func (*Table) GetHeaders ¶ added in v0.30.0
GetHeaders returns the column headers. Satisfies the table.TableProvider interface.
func (*Table) GetRows ¶ added in v0.30.0
GetRows returns the data rows. Satisfies the table.TableProvider interface.
func (*Table) ToMapSlice ¶ added in v0.30.0
ToMapSlice converts Table to a slice of maps (header→cell). Returns nil if data is nil or has no headers.
func (*Table) Validate ¶ added in v0.30.0
Validate checks the Table for consistency. Returns an error if rows are nil, or if the footer column count does not match the header count.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
data := output.NewTable([]string{"Name", "Count"})
data.AddRow([]string{"Alice", "10"})
data.SetFooter([]string{"Total", "10"})
fmt.Println(data.Validate())
}
Output: <nil>
type TableBuilder ¶ added in v0.30.0
type TableBuilder struct {
// contains filtered or unexported fields
}
TableBuilder is the CQRS write-side builder for tabular data. It provides a fluent construction API, then copies the result into a *Table via Build(). The returned Table is a defensive copy — further mutations to the builder do not affect previously built Tables. Note: *Table has exported fields; callers SHOULD treat it as read-only after Build(), but Go does not enforce this at the type level.
Usage:
t := NewTableBuilder().
SetHeaders("Name", "Status").
AddRow("Compile", "done").
AddRow("Test", "done").
SetFooter("Total", "2 tasks").
Build()
func NewTableBuilder ¶ added in v0.30.0
func NewTableBuilder() *TableBuilder
NewTableBuilder creates a new TableBuilder.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
tbl := output.NewTableBuilder().
SetHeaders("Name", "Status", "Duration").
AddRow("Compile", "done", "2.1s").
AddRow("Test", "done", "5.3s").
SetFooter("Total", "", "7.4s").
Build()
fmt.Printf("%d rows, %d cols\n", tbl.RowCount(), tbl.ColCount())
}
Output:
func (*TableBuilder) AddRow ¶ added in v0.30.0
func (b *TableBuilder) AddRow(row ...string) *TableBuilder
AddRow appends a data row.
func (*TableBuilder) AddRows ¶ added in v0.30.0
func (b *TableBuilder) AddRows(rows ...[]string) *TableBuilder
AddRows appends multiple data rows.
func (*TableBuilder) Build ¶ added in v0.30.0
func (b *TableBuilder) Build() *Table
Build returns a defensive copy of the builder's data as a *Table. The returned slices are copied — further mutations to the builder do not affect previously built Tables. Callers SHOULD treat the result as read-only, though Go does not enforce immutability on *Table.
func (*TableBuilder) SetFooter ¶ added in v0.30.0
func (b *TableBuilder) SetFooter(footer ...string) *TableBuilder
SetFooter sets the footer row.
func (*TableBuilder) SetHeaders ¶ added in v0.30.0
func (b *TableBuilder) SetHeaders(headers ...string) *TableBuilder
SetHeaders sets the column headers.
type TableMarshaler ¶ added in v0.30.0
type TableMarshaler func(w io.Writer, data *Table, opts RenderOptions) error
TableMarshaler renders Table in a specific format to a writer.
type TableRenderer ¶
type TableRenderer interface {
Renderer
// SetHeaders sets the column headers.
SetHeaders(headers []string)
// AddRow adds a data row.
AddRow(row []string)
}
TableRenderer defines the interface for table format renderers.
type TableStore ¶ added in v0.30.0
type TableStore struct {
// contains filtered or unexported fields
}
TableStore provides common table data storage for renderers.
func (*TableStore) AddRow ¶ added in v0.30.0
func (b *TableStore) AddRow(row []string)
AddRow adds a data row.
func (*TableStore) Data ¶ added in v0.30.0
func (b *TableStore) Data() *Table
Data returns the underlying Table.
func (*TableStore) HasFooter ¶ added in v0.30.0
func (b *TableStore) HasFooter() bool
HasFooter returns true if a footer row is present.
func (*TableStore) SetData ¶ added in v0.30.0
func (b *TableStore) SetData(data *Table)
SetData sets the table data directly.
func (*TableStore) SetFooter ¶ added in v0.30.0
func (b *TableStore) SetFooter(footer []string)
SetFooter sets the footer row.
func (*TableStore) SetHeaders ¶ added in v0.30.0
func (b *TableStore) SetHeaders(headers []string)
SetHeaders sets the column headers.
type TableToGraphOption ¶ added in v0.30.0
type TableToGraphOption func(*tableToGraphConfig)
TableToGraphOption configures a TableToGraph projection.
func WithGraphNodeLabelFunc ¶ added in v0.30.0
func WithGraphNodeLabelFunc(fn GraphNodeLabelFunc) TableToGraphOption
WithGraphNodeLabelFunc overrides the default label function used by TableToGraph to derive each node's label from its row.
type TreeBuilder ¶ added in v0.30.0
type TreeBuilder struct {
// contains filtered or unexported fields
}
TreeBuilder is the CQRS write-side builder for tree data. It provides a fluent construction API for assembling a tree, then returns the assembled *TreeNode (root) via Build(). Note: *TreeNode has exported fields and an AddChild method; callers SHOULD treat the result as read-only after Build(), but Go does not enforce this at the type level.
Usage:
root := NewTreeBuilder().
SetRoot("build", "Build").
AddChild("build", "compile", "Compile").
AddChild("build", "lint", "Lint").
AddChild("compile", "test", "Test").
Build()
func NewTreeBuilder ¶ added in v0.30.0
func NewTreeBuilder() *TreeBuilder
NewTreeBuilder creates a new TreeBuilder.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
root := output.NewTreeBuilder().
SetRoot("build", "Build").
AddChild("build", "compile", "Compile").
AddChild("build", "test", "Test").
AddChild("compile", "lint", "Lint").
Build()
fmt.Println(root.Label.Get())
}
Output:
func (*TreeBuilder) AddChild ¶ added in v0.30.0
func (b *TreeBuilder) AddChild(parentID, id, label string) *TreeBuilder
AddChild adds a child node under the specified parent ID. If the parent ID is not found, the child is silently skipped.
func (*TreeBuilder) AddChildren ¶ added in v0.30.0
func (b *TreeBuilder) AddChildren(parentID string, children ...[2]string) *TreeBuilder
AddChildren adds multiple child nodes under the specified parent ID. Each child is specified as an (id, label) pair. If the parent ID is not found, all children are silently skipped.
func (*TreeBuilder) Build ¶ added in v0.30.0
func (b *TreeBuilder) Build() *TreeNode
Build returns the root node of the assembled tree. Returns nil if SetRoot was never called.
func (*TreeBuilder) SetRoot ¶ added in v0.30.0
func (b *TreeBuilder) SetRoot(id, label string) *TreeBuilder
SetRoot creates and sets the root node.
type TreeNode ¶
type TreeNode struct {
// ID is the unique identifier for the node.
ID TreeNodeID
// Label is the display text for the node.
Label TreeNodeLabel
// Children holds the child nodes.
Children []*TreeNode
// Metadata holds arbitrary key-value pairs for custom data.
Metadata map[string]string
// contains filtered or unexported fields
}
TreeNode represents a node in a tree structure.
func GraphToTree ¶ added in v0.30.0
GraphToTree converts a Graph into a TreeNode tree. The first node with no incoming edges becomes the root; outgoing edges define parent→child relationships. If the graph contains cycles, each node is visited at most once (cycle guard). If the graph has multiple roots, only the first root's subtree is returned. This is a pure projection — the input Graph is not modified.
Example ¶
package main
import (
"fmt"
"github.com/larsartmann/go-output"
)
func main() {
b := output.NewGraphBuilder()
b.AddNode(*output.NewGraphNode("root", "Root"))
b.AddNode(*output.NewGraphNode("child", "Child"))
b.AddEdge(*output.NewGraphEdge("root", "child"))
g := b.Build()
root := output.GraphToTree(g)
fmt.Println(root.Label.Get())
}
Output:
func NewTreeNode ¶
NewTreeNode creates a new TreeNode with the given ID and label.
type TreeNodeID ¶
type TreeNodeID = id.ID[TreeNodeIDBrand, string]
TreeNodeID is a branded identifier for tree nodes.
type TreeNodeIDBrand ¶
type TreeNodeIDBrand struct{}
TreeNodeIDBrand is the brand type for tree node IDs.
type TreeNodeIDFunc ¶
TreeNodeIDFunc resolves a TreeNode's ID for a specific graph format.
type TreeNodeLabel ¶
type TreeNodeLabel = id.ID[TreeNodeLabelBrand, string]
TreeNodeLabel is a branded identifier for tree node labels.
type TreeNodeLabelBrand ¶
type TreeNodeLabelBrand struct{}
TreeNodeLabelBrand is the brand type for tree node labels.
type TreeRenderer ¶ added in v0.30.0
type TreeRenderer interface {
Renderer
// SetRoot sets the root node of the tree.
SetRoot(node *TreeNode)
}
TreeRenderer defines the interface for tree format renderers.
type UnknownRenderer ¶ added in v0.30.0
type UnknownRenderer func(w io.Writer, data any, opts RenderOptions) error
UnknownRenderer renders arbitrary data (any) in a specific format to a writer.
type UnsupportedFormatError ¶ added in v0.5.0
type UnsupportedFormatError struct {
Format Format
}
UnsupportedFormatError is returned when RenderTable cannot handle a format.
func (*UnsupportedFormatError) Error ¶ added in v0.5.0
func (e *UnsupportedFormatError) Error() string