blob: dc92deca78461ab9ab00f11757d599c149516b5f [file] [log] [blame]
Scott Baker2c0ebda2019-05-06 16:55:47 -07001/*
2 * Copyright 2019-present Ciena Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package format
17
18import (
19 "io"
20 "reflect"
21 "regexp"
22 "strings"
23 "text/tabwriter"
24 "text/template"
25 "text/template/parse"
26)
27
28var nameFinder = regexp.MustCompile(`\.([_A-Za-z0-9]*)}}`)
29
30type Format string
31
32func (f Format) IsTable() bool {
33 return strings.HasPrefix(string(f), "table")
34}
35
36func (f Format) Execute(writer io.Writer, withHeaders bool, data interface{}) error {
37 var tabWriter *tabwriter.Writer = nil
38 format := f
39
40 if f.IsTable() {
41 tabWriter = tabwriter.NewWriter(writer, 0, 4, 4, ' ', 0)
42 format = Format(strings.TrimPrefix(string(f), "table"))
43 }
44
45 tmpl, err := template.New("output").Parse(string(format))
46 if err != nil {
47 return err
48 }
49
50 if f.IsTable() && withHeaders {
51 var header string
52 for _, n := range tmpl.Tree.Root.Nodes {
53 switch n.Type() {
54 case parse.NodeText:
55 header += n.String()
56 case parse.NodeString:
57 header += n.String()
58 case parse.NodeAction:
59 found := nameFinder.FindStringSubmatch(n.String())
60 if len(found) == 2 {
61 header += strings.ToUpper(found[1])
62 }
63 }
64 }
65 tabWriter.Write([]byte(header))
66 tabWriter.Write([]byte("\n"))
67
68 slice := reflect.ValueOf(data)
69 if slice.Kind() == reflect.Slice {
70 for i := 0; i < slice.Len(); i++ {
71 tmpl.Execute(tabWriter, slice.Index(i).Interface())
72 tabWriter.Write([]byte("\n"))
73 }
74 } else {
75 tmpl.Execute(tabWriter, data)
76 tabWriter.Write([]byte("\n"))
77 }
78 tabWriter.Flush()
79 return nil
80 }
81
82 slice := reflect.ValueOf(data)
83 if slice.Kind() == reflect.Slice {
84 for i := 0; i < slice.Len(); i++ {
85 tmpl.Execute(writer, slice.Index(i).Interface())
86 writer.Write([]byte("\n"))
87 }
88 } else {
89 tmpl.Execute(writer, data)
90 writer.Write([]byte("\n"))
91 }
92 return nil
93
94}