blob: af92a0340e583c7a2a5eafa697ce16cd8b24c910 [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -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, nameLimit int, 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 if nameLimit > 0 {
62 parts := strings.Split(found[1], ".")
63 start := len(parts) - nameLimit
64 if start < 0 {
65 start = 0
66 }
67 header += strings.ToUpper(strings.Join(parts[start:], "."))
68 } else {
69 header += strings.ToUpper(found[1])
70 }
71 }
72 }
73 }
74 tabWriter.Write([]byte(header))
75 tabWriter.Write([]byte("\n"))
76
77 slice := reflect.ValueOf(data)
78 if slice.Kind() == reflect.Slice {
79 for i := 0; i < slice.Len(); i++ {
80 tmpl.Execute(tabWriter, slice.Index(i).Interface())
81 tabWriter.Write([]byte("\n"))
82 }
83 } else {
84 tmpl.Execute(tabWriter, data)
85 tabWriter.Write([]byte("\n"))
86 }
87 tabWriter.Flush()
88 return nil
89 }
90
91 slice := reflect.ValueOf(data)
92 if slice.Kind() == reflect.Slice {
93 for i := 0; i < slice.Len(); i++ {
94 tmpl.Execute(writer, slice.Index(i).Interface())
95 writer.Write([]byte("\n"))
96 }
97 } else {
98 tmpl.Execute(writer, data)
99 writer.Write([]byte("\n"))
100 }
101 return nil
102
103}