in openapi/output_filter.go [104:226]
func (a *TableOutputFilter) FormatTable(rowPath string, colNames []string, v interface{}) (string, error) {
// Add row number
if v, ok := OutputFlag(a.ctx.Flags()).GetFieldValue("num"); ok {
if v == "true" {
colNames = append([]string{"Num"}, colNames...)
}
}
rows, err := jmespath.Search(rowPath, v)
if err != nil {
return "", fmt.Errorf("jmespath: '%s' failed %s", rowPath, err)
}
rowsArray, ok := rows.([]interface{})
if !ok {
return "", fmt.Errorf("jmespath: '%s' failed Need Array Expr", rowPath)
}
// delete date type is struct
// 1 = object, 2 = array
dataType := 1
if len(rowsArray) > 0 {
_, ok := rowsArray[0].(map[string]interface{})
if !ok {
// check if it is an array
if isArrayOrSlice(rowsArray[0]) {
dataType = 2
}
}
}
colNamesArray := make([]string, 0)
colIndexArray := make([]int, 0)
if dataType == 2 {
// all colNames must be string:number format
for _, colName := range colNames {
// Num ignore
if colName == "Num" {
colNamesArray = append(colNamesArray, colName)
continue
}
if !strings.Contains(colName, ":") {
return "", fmt.Errorf("colNames: %s must be string:number format, like 'name:0', 0 is the array index", colName)
}
// split colName to name and number, must be two parts
parts := strings.Split(colName, ":")
if len(parts) != 2 {
return "", fmt.Errorf("colNames: %s must be string:number format, like 'name:0', 0 is the array index", colName)
}
// check if number is a number, use regex match
if !isNumber(parts[1]) {
return "", fmt.Errorf("colNames: %s must be string:number format, like 'name:0', 0 is the array index", colName)
}
colNamesArray = append(colNamesArray, parts[0])
num, err := strconv.Atoi(parts[1])
if err != nil {
return "", fmt.Errorf("colNames: %s must be string:number format, like 'name:0', 0 is the array index", colName)
}
colIndexArray = append(colIndexArray, num)
}
}
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
format := strings.Repeat("%v\t ", len(colNames)-1) + "%v"
w := tabwriter.NewWriter(writer, 0, 0, 1, ' ', tabwriter.Debug)
if dataType == 1 {
fmt.Fprintln(w, fmt.Sprintf(format, toIntfArray(colNames)...))
separator := ""
for i, colName := range colNames {
separator = separator + strings.Repeat("-", len(colName))
if i < len(colNames)-1 {
separator = separator + "\t "
}
}
fmt.Fprintln(w, separator)
} else {
fmt.Fprintln(w, fmt.Sprintf(format, toIntfArray(colNamesArray)...))
separator := ""
for i, colNameArray := range colNamesArray {
separator = separator + strings.Repeat("-", len(colNameArray))
if i < len(colNamesArray)-1 {
separator = separator + "\t "
}
}
fmt.Fprintln(w, separator)
}
for i, row := range rowsArray {
r := make([]string, 0)
var s string
var index int
if v, ok := OutputFlag(a.ctx.Flags()).GetFieldValue("num"); ok {
if v == "true" {
s = fmt.Sprintf("%v", i)
r = append(r, s)
index = 1
}
}
if dataType == 1 {
for _, colName := range colNames[index:] {
v, _ := jmespath.Search(colName, row)
s = fmt.Sprintf("%v", v)
r = append(r, s)
}
} else {
for _, colIndex := range colIndexArray {
v, _ := jmespath.Search(fmt.Sprintf("[%d]", colIndex), row)
s = fmt.Sprintf("%v", v)
r = append(r, s)
}
}
fmt.Fprintln(w, fmt.Sprintf(format, toIntfArray(r)...))
}
w.Flush()
writer.Flush()
return buf.String(), nil
}