Added renderers for the other types
This commit is contained in:
parent
33783ee688
commit
9204947d5e
52
internal/dynamo-browse/models/itemrender/coll.go
Normal file
52
internal/dynamo-browse/models/itemrender/coll.go
Normal 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
|
||||||
|
}
|
49
internal/dynamo-browse/models/itemrender/itemdisp.go
Normal file
49
internal/dynamo-browse/models/itemrender/itemdisp.go
Normal 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
|
||||||
|
}
|
15
internal/dynamo-browse/models/itemrender/nils.go
Normal file
15
internal/dynamo-browse/models/itemrender/nils.go
Normal 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
|
||||||
|
}
|
82
internal/dynamo-browse/models/itemrender/scalars.go
Normal file
82
internal/dynamo-browse/models/itemrender/scalars.go
Normal 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
|
||||||
|
}
|
51
internal/dynamo-browse/models/itemrender/sets.go
Normal file
51
internal/dynamo-browse/models/itemrender/sets.go
Normal 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}
|
||||||
|
}
|
10
internal/dynamo-browse/models/itemrender/utils.go
Normal file
10
internal/dynamo-browse/models/itemrender/utils.go
Normal 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)
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
package models
|
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
|
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) {
|
func (i Item) AttributeValueAsString(key string) (string, bool) {
|
||||||
return attributeToString(i[key])
|
return attributeToString(i[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i Item) Renderer(key string) itemrender.Renderer {
|
||||||
|
return itemrender.ToRenderer(i[key])
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@ package dynamoitemview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/lmika/awstools/internal/dynamo-browse/models/itemrender"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
|
||||||
"github.com/charmbracelet/bubbles/viewport"
|
"github.com/charmbracelet/bubbles/viewport"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
@ -83,15 +84,8 @@ func (m *Model) updateViewportToSelectedMessage() {
|
||||||
viewportContent := &strings.Builder{}
|
viewportContent := &strings.Builder{}
|
||||||
tabWriter := tabwriter.NewWriter(viewportContent, 0, 1, 1, ' ', 0)
|
tabWriter := tabwriter.NewWriter(viewportContent, 0, 1, 1, ' ', 0)
|
||||||
for _, colName := range m.currentResultSet.Columns {
|
for _, colName := range m.currentResultSet.Columns {
|
||||||
switch colVal := m.selectedItem[colName].(type) {
|
if r := m.selectedItem.Renderer(colName); r != nil {
|
||||||
case nil:
|
m.renderItem(tabWriter, "", colName, r)
|
||||||
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)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,3 +94,12 @@ func (m *Model) updateViewportToSelectedMessage() {
|
||||||
m.viewport.Height = m.h - m.frameTitle.HeaderHeight()
|
m.viewport.Height = m.h - m.frameTitle.HeaderHeight()
|
||||||
m.viewport.SetContent(viewportContent.String())
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,18 +6,17 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
|
||||||
table "github.com/calyptia/go-bubble-table"
|
table "github.com/calyptia/go-bubble-table"
|
||||||
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
markedRowStyle = lipgloss.NewStyle().
|
markedRowStyle = lipgloss.NewStyle().
|
||||||
Background(lipgloss.Color("#e1e1e1"))
|
Background(lipgloss.Color("#e1e1e1"))
|
||||||
dirtyRowStyle = lipgloss.NewStyle().
|
dirtyRowStyle = lipgloss.NewStyle().
|
||||||
Foreground(lipgloss.Color("#e13131"))
|
Foreground(lipgloss.Color("#e13131"))
|
||||||
newRowStyle = lipgloss.NewStyle().
|
newRowStyle = lipgloss.NewStyle().
|
||||||
Foreground(lipgloss.Color("#31e131"))
|
Foreground(lipgloss.Color("#31e131"))
|
||||||
)
|
)
|
||||||
|
|
||||||
type itemTableRow struct {
|
type itemTableRow struct {
|
||||||
|
@ -37,15 +36,8 @@ func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
|
||||||
sb.WriteString("\t")
|
sb.WriteString("\t")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch colVal := mtr.item[colName].(type) {
|
if r := mtr.item.Renderer(colName); r != nil {
|
||||||
case nil:
|
sb.WriteString(r.StringValue())
|
||||||
sb.WriteString("(nil)")
|
|
||||||
case *types.AttributeValueMemberS:
|
|
||||||
sb.WriteString(colVal.Value)
|
|
||||||
case *types.AttributeValueMemberN:
|
|
||||||
sb.WriteString(colVal.Value)
|
|
||||||
default:
|
|
||||||
sb.WriteString("(other)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/brianvoe/gofakeit/v6"
|
"github.com/brianvoe/gofakeit/v6"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/aws"
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
"github.com/aws/aws-sdk-go-v2/config"
|
"github.com/aws/aws-sdk-go-v2/config"
|
||||||
|
@ -66,13 +67,22 @@ func main() {
|
||||||
for i := 0; i < totalItems; i++ {
|
for i := 0; i < totalItems; i++ {
|
||||||
key := uuid.New().String()
|
key := uuid.New().String()
|
||||||
if err := tableService.Put(ctx, tableInfo, models.Item{
|
if err := tableService.Put(ctx, tableInfo, models.Item{
|
||||||
"pk": &types.AttributeValueMemberS{Value: key},
|
"pk": &types.AttributeValueMemberS{Value: key},
|
||||||
"sk": &types.AttributeValueMemberS{Value: key},
|
"sk": &types.AttributeValueMemberS{Value: key},
|
||||||
"name": &types.AttributeValueMemberS{Value: gofakeit.Name()},
|
"name": &types.AttributeValueMemberS{Value: gofakeit.Name()},
|
||||||
"address": &types.AttributeValueMemberS{Value: gofakeit.Address().Address},
|
"address": &types.AttributeValueMemberS{Value: gofakeit.Address().Address},
|
||||||
"city": &types.AttributeValueMemberS{Value: gofakeit.Address().City},
|
"city": &types.AttributeValueMemberS{Value: gofakeit.Address().City},
|
||||||
"phone": &types.AttributeValueMemberS{Value: gofakeit.Phone()},
|
"phone": &types.AttributeValueMemberN{Value: gofakeit.Phone()},
|
||||||
"web": &types.AttributeValueMemberS{Value: gofakeit.URL()},
|
"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 {
|
}); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue