Added renderers for the other types

This commit is contained in:
Leon Mika 2022-06-02 21:43:14 +10:00
parent 33783ee688
commit 9204947d5e
10 changed files with 302 additions and 31 deletions

View file

@ -0,0 +1,52 @@
package itemrender
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"sort"
)
type ListRenderer types.AttributeValueMemberL
func (sr *ListRenderer) TypeName() string {
return "L"
}
func (sr *ListRenderer) StringValue() string {
if len(sr.Value) == 1 {
return fmt.Sprintf("(1 item)")
}
return fmt.Sprintf("(%d items)", len(sr.Value))
}
func (sr *ListRenderer) SubItems() []SubItem {
subitems := make([]SubItem, len(sr.Value))
for i, r := range sr.Value {
subitems[i] = SubItem{Key: fmt.Sprint(i), Value: ToRenderer(r)}
}
return subitems
}
type MapRenderer types.AttributeValueMemberM
func (sr *MapRenderer) TypeName() string {
return "M"
}
func (sr *MapRenderer) StringValue() string {
if len(sr.Value) == 1 {
return fmt.Sprintf("(1 item)")
}
return fmt.Sprintf("(%d items)", len(sr.Value))
}
func (sr *MapRenderer) SubItems() []SubItem {
subitems := make([]SubItem, 0)
for k, r := range sr.Value {
subitems = append(subitems, SubItem{Key: k, Value: ToRenderer(r)})
}
sort.Slice(subitems, func(i, j int) bool {
return subitems[i].Key < subitems[j].Key
})
return subitems
}

View file

@ -0,0 +1,49 @@
package itemrender
import "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
type Renderer interface {
TypeName() string
StringValue() string
SubItems() []SubItem
}
func ToRenderer(v types.AttributeValue) Renderer {
switch colVal := v.(type) {
case nil:
return nil
case *types.AttributeValueMemberS:
x := StringRenderer(*colVal)
return &x
case *types.AttributeValueMemberN:
x := NumberRenderer(*colVal)
return &x
case *types.AttributeValueMemberBOOL:
x := BoolRenderer(*colVal)
return &x
case *types.AttributeValueMemberNULL:
x := NullRenderer(*colVal)
return &x
case *types.AttributeValueMemberB:
x := BinaryRenderer(*colVal)
return &x
case *types.AttributeValueMemberL:
x := ListRenderer(*colVal)
return &x
case *types.AttributeValueMemberM:
x := MapRenderer(*colVal)
return &x
case *types.AttributeValueMemberBS:
return newBinarySetRenderer(colVal)
case *types.AttributeValueMemberNS:
return newNumberSetRenderer(colVal)
case *types.AttributeValueMemberSS:
return newStringSetRenderer(colVal)
}
return OtherRenderer{}
}
type SubItem struct {
Key string
Value Renderer
}

View file

@ -0,0 +1,15 @@
package itemrender
type OtherRenderer struct{}
func (u OtherRenderer) TypeName() string {
return "(other)"
}
func (u OtherRenderer) StringValue() string {
return "(other)"
}
func (u OtherRenderer) SubItems() []SubItem {
return nil
}

View file

@ -0,0 +1,82 @@
package itemrender
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
type StringRenderer types.AttributeValueMemberS
func (sr *StringRenderer) TypeName() string {
return "S"
}
func (sr *StringRenderer) StringValue() string {
return sr.Value
}
func (sr *StringRenderer) SubItems() []SubItem {
return nil
}
type NumberRenderer types.AttributeValueMemberN
func (sr *NumberRenderer) TypeName() string {
return "N"
}
func (sr *NumberRenderer) StringValue() string {
return sr.Value
}
func (sr *NumberRenderer) SubItems() []SubItem {
return nil
}
type BoolRenderer types.AttributeValueMemberBOOL
func (sr *BoolRenderer) TypeName() string {
return "BOOL"
}
func (sr *BoolRenderer) StringValue() string {
if sr.Value {
return "True"
}
return "False"
}
func (sr *BoolRenderer) SubItems() []SubItem {
return nil
}
type BinaryRenderer types.AttributeValueMemberB
func (sr *BinaryRenderer) TypeName() string {
return "B"
}
func (sr *BinaryRenderer) StringValue() string {
if len(sr.Value) == 1 {
return fmt.Sprintf("(1 byte)")
}
return fmt.Sprintf("(%d bytes)", len(sr.Value))
}
func (sr *BinaryRenderer) SubItems() []SubItem {
return nil
}
type NullRenderer types.AttributeValueMemberNULL
func (sr *NullRenderer) TypeName() string {
return "NULL"
}
func (sr *NullRenderer) StringValue() string {
return "null"
}
func (sr *NullRenderer) SubItems() []SubItem {
return nil
}

View file

@ -0,0 +1,51 @@
package itemrender
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
type GenericRenderer struct {
typeName string
subitemValue []Renderer
}
func (sr *GenericRenderer) TypeName() string {
return sr.typeName
}
func (sr *GenericRenderer) StringValue() string {
return cardinality(len(sr.subitemValue), "item", "items")
}
func (sr *GenericRenderer) SubItems() []SubItem {
subitems := make([]SubItem, len(sr.subitemValue))
for i, r := range sr.subitemValue {
subitems[i] = SubItem{Key: fmt.Sprint(i), Value: r}
}
return subitems
}
func newBinarySetRenderer(v *types.AttributeValueMemberBS) *GenericRenderer {
vs := make([]Renderer, len(v.Value))
for i, b := range v.Value {
vs[i] = &BinaryRenderer{Value: b}
}
return &GenericRenderer{typeName: "BS", subitemValue: vs}
}
func newNumberSetRenderer(v *types.AttributeValueMemberNS) *GenericRenderer {
vs := make([]Renderer, len(v.Value))
for i, n := range v.Value {
vs[i] = &NumberRenderer{Value: n}
}
return &GenericRenderer{typeName: "NS", subitemValue: vs}
}
func newStringSetRenderer(v *types.AttributeValueMemberSS) *GenericRenderer {
vs := make([]Renderer, len(v.Value))
for i, s := range v.Value {
vs[i] = &StringRenderer{Value: s}
}
return &GenericRenderer{typeName: "SS", subitemValue: vs}
}

View file

@ -0,0 +1,10 @@
package itemrender
import "fmt"
func cardinality(c int, single, multi string) string {
if c == 1 {
return fmt.Sprintf("(%d %v)", c, single)
}
return fmt.Sprintf("(%d %v)", c, multi)
}

View file

@ -1,6 +1,9 @@
package models
import "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
import (
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/lmika/awstools/internal/dynamo-browse/models/itemrender"
)
type Item map[string]types.AttributeValue
@ -28,3 +31,7 @@ func (i Item) KeyValue(info *TableInfo) map[string]types.AttributeValue {
func (i Item) AttributeValueAsString(key string) (string, bool) {
return attributeToString(i[key])
}
func (i Item) Renderer(key string) itemrender.Renderer {
return itemrender.ToRenderer(i[key])
}

View file

@ -2,10 +2,11 @@ package dynamoitemview
import (
"fmt"
"github.com/lmika/awstools/internal/dynamo-browse/models/itemrender"
"io"
"strings"
"text/tabwriter"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
@ -83,15 +84,8 @@ func (m *Model) updateViewportToSelectedMessage() {
viewportContent := &strings.Builder{}
tabWriter := tabwriter.NewWriter(viewportContent, 0, 1, 1, ' ', 0)
for _, colName := range m.currentResultSet.Columns {
switch colVal := m.selectedItem[colName].(type) {
case nil:
break
case *types.AttributeValueMemberS:
fmt.Fprintf(tabWriter, "%v\tS\t%s\n", colName, colVal.Value)
case *types.AttributeValueMemberN:
fmt.Fprintf(tabWriter, "%v\tN\t%s\n", colName, colVal.Value)
default:
fmt.Fprintf(tabWriter, "%v\t?\t%s\n", colName, "(other)")
if r := m.selectedItem.Renderer(colName); r != nil {
m.renderItem(tabWriter, "", colName, r)
}
}
@ -100,3 +94,12 @@ func (m *Model) updateViewportToSelectedMessage() {
m.viewport.Height = m.h - m.frameTitle.HeaderHeight()
m.viewport.SetContent(viewportContent.String())
}
func (m *Model) renderItem(w io.Writer, prefix string, name string, r itemrender.Renderer) {
fmt.Fprintf(w, "%s%v\t%s\t%s\n", prefix, name, r.TypeName(), r.StringValue())
if subitems := r.SubItems(); len(subitems) > 0 {
for _, si := range subitems {
m.renderItem(w, prefix+" ", si.Key, si.Value)
}
}
}

View file

@ -6,18 +6,17 @@ import (
"io"
"strings"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
table "github.com/calyptia/go-bubble-table"
"github.com/lmika/awstools/internal/dynamo-browse/models"
)
var (
markedRowStyle = lipgloss.NewStyle().
Background(lipgloss.Color("#e1e1e1"))
Background(lipgloss.Color("#e1e1e1"))
dirtyRowStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#e13131"))
Foreground(lipgloss.Color("#e13131"))
newRowStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#31e131"))
Foreground(lipgloss.Color("#31e131"))
)
type itemTableRow struct {
@ -37,15 +36,8 @@ func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
sb.WriteString("\t")
}
switch colVal := mtr.item[colName].(type) {
case nil:
sb.WriteString("(nil)")
case *types.AttributeValueMemberS:
sb.WriteString(colVal.Value)
case *types.AttributeValueMemberN:
sb.WriteString(colVal.Value)
default:
sb.WriteString("(other)")
if r := mtr.item.Renderer(colName); r != nil {
sb.WriteString(r.StringValue())
}
}

View file

@ -5,6 +5,7 @@ import (
"github.com/brianvoe/gofakeit/v6"
"github.com/google/uuid"
"log"
"strconv"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
@ -66,13 +67,22 @@ func main() {
for i := 0; i < totalItems; i++ {
key := uuid.New().String()
if err := tableService.Put(ctx, tableInfo, models.Item{
"pk": &types.AttributeValueMemberS{Value: key},
"sk": &types.AttributeValueMemberS{Value: key},
"name": &types.AttributeValueMemberS{Value: gofakeit.Name()},
"address": &types.AttributeValueMemberS{Value: gofakeit.Address().Address},
"city": &types.AttributeValueMemberS{Value: gofakeit.Address().City},
"phone": &types.AttributeValueMemberS{Value: gofakeit.Phone()},
"web": &types.AttributeValueMemberS{Value: gofakeit.URL()},
"pk": &types.AttributeValueMemberS{Value: key},
"sk": &types.AttributeValueMemberS{Value: key},
"name": &types.AttributeValueMemberS{Value: gofakeit.Name()},
"address": &types.AttributeValueMemberS{Value: gofakeit.Address().Address},
"city": &types.AttributeValueMemberS{Value: gofakeit.Address().City},
"phone": &types.AttributeValueMemberN{Value: gofakeit.Phone()},
"web": &types.AttributeValueMemberS{Value: gofakeit.URL()},
"inOffice": &types.AttributeValueMemberBOOL{Value: gofakeit.Bool()},
"ratings": &types.AttributeValueMemberL{Value: []types.AttributeValue{
&types.AttributeValueMemberS{Value: gofakeit.Adverb()},
&types.AttributeValueMemberN{Value: strconv.Itoa(int(gofakeit.Int32()))},
}},
"values": &types.AttributeValueMemberM{Value: map[string]types.AttributeValue{
"adverb": &types.AttributeValueMemberS{Value: gofakeit.Adverb()},
"int": &types.AttributeValueMemberN{Value: strconv.Itoa(int(gofakeit.Int32()))},
}},
}); err != nil {
log.Fatalln(err)
}