From 9dc59694a2de1242d14b8bf52070da94be733d1d Mon Sep 17 00:00:00 2001 From: Inhere Date: Sun, 26 Mar 2023 11:50:10 +0800 Subject: [PATCH] :necktie: up(show): MList support struct and any map data for render --- show/base.go | 5 +++- show/list.go | 65 ++++++++++++++++++++++++++++++++++------------------ show/show.go | 2 +- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/show/base.go b/show/base.go index 9d61d7e..34a557e 100644 --- a/show/base.go +++ b/show/base.go @@ -270,11 +270,14 @@ func (item *Item) IsEmpty() bool { case reflect.Interface, reflect.Slice, reflect.Ptr: return item.rftVal.IsNil() } - return false + return !item.rftVal.IsValid() } // ValString get func (item *Item) ValString() string { + if item.IsEmpty() { + return "" + } return strutil.QuietString(item.rftVal.Interface()) } diff --git a/show/list.go b/show/list.go index 08b6946..2a83f9f 100644 --- a/show/list.go +++ b/show/list.go @@ -7,6 +7,8 @@ import ( "github.com/gookit/color" "github.com/gookit/goutil/arrutil" "github.com/gookit/goutil/maputil" + "github.com/gookit/goutil/reflects" + "github.com/gookit/goutil/structs" "github.com/gookit/goutil/strutil" ) @@ -28,6 +30,19 @@ type ListOption struct { // ListOpFunc define type ListOpFunc func(opts *ListOption) +// NewListOption instance +func NewListOption() *ListOption { + return &ListOption{ + SepChar: " ", + KeyStyle: "info", + // more + LeftIndent: " ", + KeyMinWidth: 8, + IgnoreEmpty: true, + TitleStyle: "comment", + } +} + /************************************************************* * List *************************************************************/ @@ -59,15 +74,7 @@ func NewList(title string, data any, fns ...ListOpFunc) *List { // base Base: Base{out: Output}, // options - Opts: &ListOption{ - SepChar: " ", - KeyStyle: "info", - LeftIndent: " ", - // more settings - KeyMinWidth: 8, - IgnoreEmpty: true, - TitleStyle: "comment", - }, + Opts: NewListOption(), } return l.WithOptionFns(fns) @@ -194,24 +201,32 @@ type Lists struct { buffer *bytes.Buffer } -// NewLists create lists -func NewLists(listMap map[string]any, fns ...ListOpFunc) *Lists { +// NewEmptyLists create empty lists +func NewEmptyLists(fns ...ListOpFunc) *Lists { ls := &Lists{ Base: Base{out: Output}, - Opts: &ListOption{ - SepChar: " ", - KeyStyle: "info", - // more - LeftIndent: " ", - KeyMinWidth: 8, - IgnoreEmpty: true, - TitleStyle: "comment", - }, + Opts: NewListOption(), } + return ls.WithOptionFns(fns) +} - for title, data := range listMap { - ls.rows = append(ls.rows, NewList(title, data)) +// NewLists create lists. allow: map[string]any, struct-ptr +func NewLists(mlist any, fns ...ListOpFunc) *Lists { + ls := NewEmptyLists() + rv := reflect.Indirect(reflect.ValueOf(mlist)) + + if rv.Kind() == reflect.Map { + reflects.EachStrAnyMap(rv, func(key string, val any) { + ls.AddSublist(key, val) + }) + } else if rv.Kind() == reflect.Struct { + for title, data := range structs.ToMap(mlist) { + ls.rows = append(ls.rows, NewList(title, data)) + } + } else { + panic("not support type: " + rv.Kind().String()) } + return ls.WithOptionFns(fns) } @@ -228,6 +243,12 @@ func (ls *Lists) WithOptions(fns ...ListOpFunc) *Lists { return ls.WithOptionFns(fns) } +// AddSublist with options func list +func (ls *Lists) AddSublist(title string, data any) *Lists { + ls.rows = append(ls.rows, NewList(title, data)) + return ls +} + // Format as string func (ls *Lists) Format() { if len(ls.rows) == 0 { diff --git a/show/show.go b/show/show.go index d21c6f2..398025c 100644 --- a/show/show.go +++ b/show/show.go @@ -73,7 +73,7 @@ func AList(title string, data any, fns ...ListOpFunc) { // show.MList(data, func(opts *ListOption) { // opts.LeftIndent = " " // }) -func MList(listMap map[string]any, fns ...ListOpFunc) { +func MList(listMap any, fns ...ListOpFunc) { NewLists(listMap).WithOptionFns(fns).Println() }