blob: eaa42eb3db24dc0de905195f374a872858268240 [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 }
David Bainbridge12f036f2019-10-15 22:09:04 +000074 if _, err = tabWriter.Write([]byte(header)); err != nil {
75 return err
76 }
77 if _, err = tabWriter.Write([]byte("\n")); err != nil {
78 return err
79 }
Zack Williamse940c7a2019-08-21 14:25:39 -070080
81 slice := reflect.ValueOf(data)
82 if slice.Kind() == reflect.Slice {
83 for i := 0; i < slice.Len(); i++ {
David Bainbridge12f036f2019-10-15 22:09:04 +000084 if err = tmpl.Execute(tabWriter, slice.Index(i).Interface()); err != nil {
85 return err
86 }
87 if _, err = tabWriter.Write([]byte("\n")); err != nil {
88 return err
89 }
Zack Williamse940c7a2019-08-21 14:25:39 -070090 }
91 } else {
David Bainbridge12f036f2019-10-15 22:09:04 +000092 if err = tmpl.Execute(tabWriter, data); err != nil {
93 return err
94 }
95 if _, err = tabWriter.Write([]byte("\n")); err != nil {
96 return err
97 }
Zack Williamse940c7a2019-08-21 14:25:39 -070098 }
99 tabWriter.Flush()
100 return nil
101 }
102
103 slice := reflect.ValueOf(data)
104 if slice.Kind() == reflect.Slice {
105 for i := 0; i < slice.Len(); i++ {
David Bainbridge12f036f2019-10-15 22:09:04 +0000106 if err = tmpl.Execute(writer, slice.Index(i).Interface()); err != nil {
107 return err
108 }
109 if _, err = writer.Write([]byte("\n")); err != nil {
110 return err
111 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700112 }
113 } else {
David Bainbridge12f036f2019-10-15 22:09:04 +0000114 if err = tmpl.Execute(writer, data); err != nil {
115 return err
116 }
117 if _, err = writer.Write([]byte("\n")); err != nil {
118 return err
119 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700120 }
121 return nil
122
123}