Skip to content

Commit

Permalink
Move helpers to output.go and add example
Browse files Browse the repository at this point in the history
  • Loading branch information
dadgar committed Feb 26, 2024
1 parent 498649e commit 4ede269
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 27 deletions.
61 changes: 61 additions & 0 deletions internal/pkg/format/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package format_test

import (
"fmt"

"github.com/hashicorp/hcp/internal/pkg/format"
"github.com/hashicorp/hcp/internal/pkg/iostreams"
)

func ExampleDisplayer() {
// Create the outputter. This is typically passed to the command.
io := iostreams.Test()
outputter := format.New(io)

// Resource is an example resource that we want to display
type Resource struct {
Name string
ID string
Description string
}

// Define the fields that we want to ExampleDisplayer
var fields = []format.Field{
format.NewField("Name", "{{ .Name }}"),
format.NewField("ID", "{{ .ID }}"),
format.NewField("Description", "{{ .Description }}"),
}

// Build our mock resources. Typically this is the response payload from an API
// request.
payload := []Resource{
{
Name: "hello",
ID: "123",
Description: "world",
},
{
Name: "another",
ID: "456",
Description: "example",
},
}

// Build the displayer
d := format.NewDisplayer(payload, format.Pretty, fields)

// Run the displayer
outputter.Display(d)

// Since the IO is a test io, manually print it
fmt.Println(io.Output.String())

// Output:
// Name: hello
// ID: 123
// Description: world
// ---
// Name: another
// ID: 456
// Description: example
}
27 changes: 0 additions & 27 deletions internal/pkg/format/helper.go

This file was deleted.

26 changes: 26 additions & 0 deletions internal/pkg/format/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ type Displayer interface {
FieldTemplates() []Field
}

// NewDisplayer creates a new Displayer with the given payload, default format,
// and fields.
func NewDisplayer[T any](payload T, defaultFormat Format, fields []Field) Displayer {
return &internalDisplayer[T]{
payload: payload,
fields: fields,
defaultFormat: defaultFormat,
}
}

type internalDisplayer[T any] struct {
payload T
fields []Field
defaultFormat Format
}

func (i *internalDisplayer[T]) DefaultFormat() Format { return i.defaultFormat }
func (i *internalDisplayer[T]) FieldTemplates() []Field { return i.fields }
func (i *internalDisplayer[T]) Payload() any { return i.payload }

// TemplatedPayload allows a Displayer to return a different payload if the
// output will be templated using the field templates. This can be useful when
// raw output (e.g. JSON) requires a specific payload but the templated output
Expand Down Expand Up @@ -70,6 +90,12 @@ type Field struct {
ValueFormat string
}

// NewField creates a new Field with the given name and value format string. See
// the Field struct for more information.
func NewField(name, valueFormat string) Field {
return Field{Name: name, ValueFormat: valueFormat}
}

// Outputter is used to output data to users in a consistent manner. The
// outputter supports outputting data in a number of Formats.
//
Expand Down

0 comments on commit 4ede269

Please sign in to comment.