-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderer.go
More file actions
145 lines (131 loc) · 5.06 KB
/
Copy pathrenderer.go
File metadata and controls
145 lines (131 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package structtable
import (
"io"
"reflect"
fs "github.com/ungerik/go-fs"
"github.com/domonda/go-errs"
)
// Renderer defines the interface for rendering struct slices into various table formats.
//
// This interface provides methods to render tabular data from Go struct slices
// into different output formats such as HTML, CSV, Excel, etc.
type Renderer interface {
// RenderHeaderRow renders the table header row with the given column titles.
RenderHeaderRow(columnTitles []string) error
// RenderRow renders a single data row with the given column values.
RenderRow(columnValues []reflect.Value) error
// Result returns the rendered table data as bytes.
Result() ([]byte, error)
// WriteResultTo writes the rendered table data to the given writer.
WriteResultTo(w io.Writer) error
// WriteResultFile writes the rendered table data to the given file.
WriteResultFile(file fs.File, perm ...fs.Permissions) error
// MIMEType returns the MIME-Type of the rendered content.
MIMEType() string
}
// Render renders a slice of structs into a table using the given Renderer.
//
// This function takes a slice of structs and renders them as a table using
// the provided Renderer implementation. It uses the ColumnMapper to determine
// column titles and extract values from the struct instances.
//
// Parameters:
// - renderer: The Renderer implementation to use for output formatting
// - structSlice: The slice of structs to render
// - renderTitleRow: Whether to include a header row with column titles
// - columnMapper: The ColumnMapper to use for field-to-column mapping
//
// Returns:
// - err: Any error that occurred during rendering
func Render(renderer Renderer, structSlice any, renderTitleRow bool, columnMapper ColumnMapper) error {
rows := reflect.ValueOf(structSlice)
if rows.Kind() != reflect.Slice {
return errs.Errorf("passed value is not a slice, but %T", structSlice)
}
columnTitles, rowReflector := columnMapper.ColumnTitlesAndRowReflector(rows.Type().Elem())
if renderTitleRow {
err := renderer.RenderHeaderRow(columnTitles)
if err != nil {
return err
}
}
for i := 0; i < rows.Len(); i++ {
err := renderer.RenderRow(rowReflector.ReflectRow(rows.Index(i)))
if err != nil {
return err
}
}
return nil
}
// RenderTo renders a slice of structs into a table and writes the result to a writer.
//
// This is a convenience function that combines Render and WriteResultTo.
// It renders the struct slice and immediately writes the result to the provided writer.
//
// Parameters:
// - writer: The io.Writer to write the rendered table to
// - renderer: The Renderer implementation to use for output formatting
// - structSlice: The slice of structs to render
// - renderTitleRow: Whether to include a header row with column titles
// - columnMapper: The ColumnMapper to use for field-to-column mapping
//
// Returns:
// - err: Any error that occurred during rendering or writing
func RenderTo(writer io.Writer, renderer Renderer, structSlice any, renderTitleRow bool, columnMapper ColumnMapper) error {
err := Render(renderer, structSlice, renderTitleRow, columnMapper)
if err != nil {
return err
}
data, err := renderer.Result()
if err != nil {
return err
}
_, err = writer.Write(data)
return err
}
// RenderBytes renders a slice of structs into a table and returns the result as bytes.
//
// This is a convenience function that combines Render and Result.
// It renders the struct slice and returns the result as a byte slice.
//
// Parameters:
// - renderer: The Renderer implementation to use for output formatting
// - structSlice: The slice of structs to render
// - renderTitleRow: Whether to include a header row with column titles
// - columnMapper: The ColumnMapper to use for field-to-column mapping
//
// Returns:
// - data: The rendered table data as bytes
// - err: Any error that occurred during rendering
func RenderBytes(renderer Renderer, structSlice any, renderTitleRow bool, columnMapper ColumnMapper) ([]byte, error) {
err := Render(renderer, structSlice, renderTitleRow, columnMapper)
if err != nil {
return nil, err
}
return renderer.Result()
}
// RenderFile renders a slice of structs into a table and writes the result to a file.
//
// This is a convenience function that combines Render and WriteResultFile.
// It renders the struct slice and immediately writes the result to the provided file.
//
// Parameters:
// - file: The fs.File to write the rendered table to
// - renderer: The Renderer implementation to use for output formatting
// - structSlice: The slice of structs to render
// - renderTitleRow: Whether to include a header row with column titles
// - columnMapper: The ColumnMapper to use for field-to-column mapping
//
// Returns:
// - err: Any error that occurred during rendering or writing
func RenderFile(file fs.File, renderer Renderer, structSlice any, renderTitleRow bool, columnMapper ColumnMapper) error {
err := Render(renderer, structSlice, renderTitleRow, columnMapper)
if err != nil {
return err
}
data, err := renderer.Result()
if err != nil {
return err
}
return file.WriteAll(data)
}