Add pretty display for struct array
This commit is contained in:
parent
541222e2d0
commit
26166489fd
131
cmd/list.go
131
cmd/list.go
@ -4,6 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"reflect"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"gocage/jail"
|
"gocage/jail"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -13,19 +14,147 @@ import (
|
|||||||
|
|
||||||
var gJails []Jail
|
var gJails []Jail
|
||||||
|
|
||||||
|
/* Pretty display of jails field
|
||||||
|
Fields to show are given in a string array parameter
|
||||||
|
Ex. : displayJails(["Name", "JID", "RootPath"])
|
||||||
|
*/
|
||||||
|
func displayStructFields(jails []Jail, valsToDisplay []string) {
|
||||||
|
/* A line is defined by :
|
||||||
|
Nr of fields
|
||||||
|
For each field :
|
||||||
|
Its name
|
||||||
|
Its max length
|
||||||
|
Its value
|
||||||
|
*/
|
||||||
|
type Field struct {
|
||||||
|
Name string
|
||||||
|
MaxLen int
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Line []Field
|
||||||
|
|
||||||
|
type Output []Line
|
||||||
|
var out Output
|
||||||
|
|
||||||
|
//fmt.Printf("%d fields in a %d items structure\n", len(valsToDisplay), len(jails))
|
||||||
|
|
||||||
|
// Browse structure to get max length and values
|
||||||
|
for _, j := range jails {
|
||||||
|
// Have to use a pointer, else reflect.Value.Elem() will panic : https://pkg.go.dev/reflect#Value.Elem
|
||||||
|
tj := &j
|
||||||
|
|
||||||
|
line := make([]Field, len(valsToDisplay))
|
||||||
|
for i, f := range valsToDisplay {
|
||||||
|
a := reflect.ValueOf(&tj).Elem()
|
||||||
|
//fmt.Printf("Struct : %s, Champ : %s\n", a.String(), f)
|
||||||
|
//fmt.Printf("%v", a.Elem().FieldByName(f).Interface())
|
||||||
|
field := Field {
|
||||||
|
Name: f,
|
||||||
|
// For now this just contains this item length, will adjust later
|
||||||
|
MaxLen: len(fmt.Sprintf("%v", a.Elem().FieldByName(f).Interface())),
|
||||||
|
Value: fmt.Sprintf("%v", a.Elem().FieldByName(f).Interface()),
|
||||||
|
}
|
||||||
|
line[i] = field
|
||||||
|
|
||||||
|
}
|
||||||
|
out = append(out, line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get real maximum length
|
||||||
|
maxlen := make([]int, len(valsToDisplay))
|
||||||
|
for i := 0; i< len(valsToDisplay); i++ {
|
||||||
|
maxlen[i] = 0
|
||||||
|
}
|
||||||
|
for _, l := range out {
|
||||||
|
for i, f := range l {
|
||||||
|
if f.MaxLen > maxlen[i] {
|
||||||
|
maxlen[i] = f.MaxLen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align maxlen to the real maximum length
|
||||||
|
for io, l := range out {
|
||||||
|
for ii, _ := range l {
|
||||||
|
// We need to access slice by index if we want to modify content
|
||||||
|
out[io][ii].MaxLen = maxlen[ii]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalLen := 0
|
||||||
|
// Add separator and 2 blank spaces
|
||||||
|
for _, f := range out[0] {
|
||||||
|
totalLen += f.MaxLen + 3
|
||||||
|
}
|
||||||
|
// Then add starting delimiter
|
||||||
|
totalLen += 1
|
||||||
|
|
||||||
|
Debug := false
|
||||||
|
if Debug == true {
|
||||||
|
for _, f := range out[0] {
|
||||||
|
fmt.Printf("%s max length : %d\n", f.Name, f.MaxLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lets draw things on the screen!
|
||||||
|
// First, headers
|
||||||
|
for i := 0; i < totalLen ; i++ {
|
||||||
|
fmt.Printf("-")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
for i, f := range out[0] {
|
||||||
|
if i == 0 {
|
||||||
|
fmt.Printf("|")
|
||||||
|
}
|
||||||
|
fmt.Printf(" %s", f.Name)
|
||||||
|
for i := len(f.Name)+1 ; i < f.MaxLen+1 ; i++ {
|
||||||
|
fmt.Printf(" ")
|
||||||
|
}
|
||||||
|
fmt.Printf(" |")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
for i := 0; i < totalLen ; i++ {
|
||||||
|
fmt.Printf("-")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
// Then display data
|
||||||
|
for _, l := range out {
|
||||||
|
for i, f := range l {
|
||||||
|
if i == 0 {
|
||||||
|
fmt.Printf("|")
|
||||||
|
}
|
||||||
|
fmt.Printf(" %s", f.Value)
|
||||||
|
for i := len(f.Value)+1 ; i < f.MaxLen+1 ; i++ {
|
||||||
|
fmt.Printf(" ")
|
||||||
|
}
|
||||||
|
fmt.Printf(" |")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
for i := 0; i < totalLen ; i++ {
|
||||||
|
fmt.Printf("-")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
func listJails(args []string) {
|
func listJails(args []string) {
|
||||||
for _, d := range viper.GetStringSlice("datastore") {
|
for _, d := range viper.GetStringSlice("datastore") {
|
||||||
listJailsFromDatastore(d)
|
listJailsFromDatastore(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, j := range (gJails) {
|
displayStructFields(gJails, []string{"JID", "Name", "RootPath"})
|
||||||
|
|
||||||
|
/* for _, j := range (gJails) {
|
||||||
if j.Running {
|
if j.Running {
|
||||||
fmt.Printf("%d ; %s ; %s ; %s\n", j.JID, j.Name, j.Config.Ip4_addr, j.Config.Release)
|
fmt.Printf("%d ; %s ; %s ; %s\n", j.JID, j.Name, j.Config.Ip4_addr, j.Config.Release)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf(" ; %s ; %s ; %s\n", j.Name, j.Config.Ip4_addr, j.Config.Release)
|
fmt.Printf(" ; %s ; %s ; %s\n", j.Name, j.Config.Ip4_addr, j.Config.Release)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user