feat: resource list and table output formatter
This commit is contained in:
@ -24,7 +24,7 @@ const (
|
||||
paramLocation = "location"
|
||||
)
|
||||
|
||||
func (h *DishesHandler) Get(ctx context.Context, params params.Container) ([]any, error) {
|
||||
func (h *DishesHandler) Get(ctx context.Context, params params.Container) (*interfaces.ResourceList, error) {
|
||||
// Read parameters
|
||||
p, err := params.GetValue(paramDate)
|
||||
if err != nil {
|
||||
@ -55,14 +55,17 @@ func (h *DishesHandler) Get(ctx context.Context, params params.Container) ([]any
|
||||
}
|
||||
|
||||
// Return
|
||||
return util.Transform(*dishes, func(i *stwbremen.Dish) any {
|
||||
d, err := resources.DishFromDTO(*i)
|
||||
if err != nil {
|
||||
return resources.Dish{}
|
||||
}
|
||||
return &interfaces.ResourceList{
|
||||
ItemKind: resources.ResourceDish,
|
||||
Items: util.Transform(*dishes, func(i *stwbremen.Dish) interfaces.Resource {
|
||||
d, err := resources.DishFromDTO(*i)
|
||||
if err != nil {
|
||||
return &resources.Dish{}
|
||||
}
|
||||
|
||||
return *d
|
||||
}), nil
|
||||
return d
|
||||
}),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ type ResourceHandler interface {
|
||||
}
|
||||
|
||||
type GetHandler interface {
|
||||
Get(ctx context.Context, params params.Container) ([]any, error)
|
||||
Get(ctx context.Context, params params.Container) (*ResourceList, error)
|
||||
}
|
||||
|
||||
type Verb string
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
package interfaces
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type Formatter interface {
|
||||
Format(object []any) (io.Reader, error)
|
||||
Format(object *ResourceList) (io.Reader, error)
|
||||
}
|
||||
|
||||
type TableOutput interface {
|
||||
ColumnNames() []string
|
||||
Columns() []any
|
||||
}
|
||||
|
||||
12
core/interfaces/resource.go
Normal file
12
core/interfaces/resource.go
Normal file
@ -0,0 +1,12 @@
|
||||
package interfaces
|
||||
|
||||
type Resource interface {
|
||||
Kind() string
|
||||
|
||||
Name() string
|
||||
}
|
||||
|
||||
type ResourceList struct {
|
||||
ItemKind string
|
||||
Items []Resource
|
||||
}
|
||||
@ -5,8 +5,11 @@ import (
|
||||
)
|
||||
|
||||
var Formatters = map[string]interfaces.Formatter{
|
||||
"json": &JsonFormatter{},
|
||||
"yaml": &YamlFormatter{},
|
||||
"go": &GoFormatter{},
|
||||
"table": nil,
|
||||
"json": &JsonFormatter{},
|
||||
"yaml": &YamlFormatter{},
|
||||
"go": &GoFormatter{},
|
||||
"table": &TableFormatter{},
|
||||
"csv": &TableFormatter{HideSummary: true, RenderFormat: tableFormatCSV},
|
||||
"html": &TableFormatter{HideSummary: true, RenderFormat: tableFormatHTML},
|
||||
"markdown": &TableFormatter{HideSummary: true, RenderFormat: tableFormatMarkdown},
|
||||
}
|
||||
|
||||
@ -4,10 +4,12 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
||||
)
|
||||
|
||||
type GoFormatter struct{}
|
||||
|
||||
func (f *GoFormatter) Format(objects []any) (io.Reader, error) {
|
||||
return strings.NewReader(fmt.Sprintf("%#v", objects)), nil
|
||||
func (f *GoFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
|
||||
return strings.NewReader(fmt.Sprintf("%#v", list)), nil
|
||||
}
|
||||
|
||||
@ -4,12 +4,14 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
||||
)
|
||||
|
||||
type JsonFormatter struct{}
|
||||
|
||||
func (f *JsonFormatter) Format(objects []any) (io.Reader, error) {
|
||||
func (f *JsonFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
|
||||
var buffer = make([]byte, 0, 1024)
|
||||
outputBuffer := bytes.NewBuffer(buffer)
|
||||
return outputBuffer, json.NewEncoder(outputBuffer).Encode(objects)
|
||||
return outputBuffer, json.NewEncoder(outputBuffer).Encode(list)
|
||||
}
|
||||
|
||||
81
core/output/table.go
Normal file
81
core/output/table.go
Normal file
@ -0,0 +1,81 @@
|
||||
package output
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
||||
"git.bissendorf.co/bissendorf/unifood/m/v2/util"
|
||||
"github.com/jedib0t/go-pretty/table"
|
||||
)
|
||||
|
||||
type tableRenderFormat string
|
||||
|
||||
const (
|
||||
tableFormatNormal tableRenderFormat = "table"
|
||||
tableFormatCSV tableRenderFormat = "csv"
|
||||
tableFormatHTML tableRenderFormat = "html"
|
||||
tableFormatMarkdown tableRenderFormat = "markdown"
|
||||
)
|
||||
|
||||
type TableFormatter struct {
|
||||
HideSummary bool
|
||||
RenderFormat tableRenderFormat
|
||||
}
|
||||
|
||||
func (f *TableFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
|
||||
|
||||
var buffer = make([]byte, 0, 1024)
|
||||
outputBuffer := bytes.NewBuffer(buffer)
|
||||
|
||||
if !f.HideSummary {
|
||||
outputBuffer.WriteString(
|
||||
fmt.Sprintf("Resource: %s\r\nCount: %v\r\n\r\n", list.ItemKind, len(list.Items)),
|
||||
)
|
||||
}
|
||||
|
||||
if len(list.Items) <= 0 {
|
||||
return outputBuffer, nil
|
||||
}
|
||||
|
||||
// Setup table
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(outputBuffer)
|
||||
t.SetStyle(table.StyleLight)
|
||||
|
||||
// Write header
|
||||
tableFormat, ok := list.Items[0].(interfaces.TableOutput)
|
||||
headerRow := []any{"Name"}
|
||||
if ok {
|
||||
columnHeaders := util.Transform(tableFormat.ColumnNames(), func(i *string) any { return *i })
|
||||
headerRow = append(headerRow, columnHeaders...)
|
||||
}
|
||||
t.AppendHeader(headerRow)
|
||||
|
||||
// Write rows
|
||||
for _, item := range list.Items {
|
||||
rowOutput := []any{item.Name()}
|
||||
|
||||
itemFormatter, ok := item.(interfaces.TableOutput)
|
||||
if ok {
|
||||
rowOutput = append(rowOutput, itemFormatter.Columns()...)
|
||||
}
|
||||
|
||||
t.AppendRow(rowOutput)
|
||||
}
|
||||
|
||||
// Render
|
||||
switch f.RenderFormat {
|
||||
case tableFormatCSV:
|
||||
t.RenderCSV()
|
||||
case tableFormatHTML:
|
||||
t.RenderHTML()
|
||||
case tableFormatMarkdown:
|
||||
t.RenderMarkdown()
|
||||
default:
|
||||
t.Render()
|
||||
}
|
||||
|
||||
return outputBuffer, nil
|
||||
}
|
||||
@ -4,13 +4,14 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
||||
"github.com/goccy/go-yaml"
|
||||
)
|
||||
|
||||
type YamlFormatter struct{}
|
||||
|
||||
func (f *YamlFormatter) Format(objects []any) (io.Reader, error) {
|
||||
buffer, err := yaml.Marshal(objects)
|
||||
func (f *YamlFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
|
||||
buffer, err := yaml.Marshal(list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user