| /* |
| * Copyright 2019-present Ciena Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package format |
| |
| import ( |
| "io" |
| "reflect" |
| "regexp" |
| "strings" |
| "text/tabwriter" |
| "text/template" |
| "text/template/parse" |
| ) |
| |
| var nameFinder = regexp.MustCompile(`\.([\._A-Za-z0-9]*)}}`) |
| |
| type Format string |
| |
| func (f Format) IsTable() bool { |
| return strings.HasPrefix(string(f), "table") |
| } |
| |
| func (f Format) Execute(writer io.Writer, withHeaders bool, nameLimit int, data interface{}) error { |
| var tabWriter *tabwriter.Writer = nil |
| format := f |
| |
| if f.IsTable() { |
| tabWriter = tabwriter.NewWriter(writer, 0, 4, 4, ' ', 0) |
| format = Format(strings.TrimPrefix(string(f), "table")) |
| } |
| |
| tmpl, err := template.New("output").Parse(string(format)) |
| if err != nil { |
| return err |
| } |
| |
| if f.IsTable() && withHeaders { |
| var header string |
| for _, n := range tmpl.Tree.Root.Nodes { |
| switch n.Type() { |
| case parse.NodeText: |
| header += n.String() |
| case parse.NodeString: |
| header += n.String() |
| case parse.NodeAction: |
| found := nameFinder.FindStringSubmatch(n.String()) |
| if len(found) == 2 { |
| if nameLimit > 0 { |
| parts := strings.Split(found[1], ".") |
| start := len(parts) - nameLimit |
| if start < 0 { |
| start = 0 |
| } |
| header += strings.ToUpper(strings.Join(parts[start:], ".")) |
| } else { |
| header += strings.ToUpper(found[1]) |
| } |
| } |
| } |
| } |
| if _, err = tabWriter.Write([]byte(header)); err != nil { |
| return err |
| } |
| if _, err = tabWriter.Write([]byte("\n")); err != nil { |
| return err |
| } |
| |
| slice := reflect.ValueOf(data) |
| if slice.Kind() == reflect.Slice { |
| for i := 0; i < slice.Len(); i++ { |
| if err = tmpl.Execute(tabWriter, slice.Index(i).Interface()); err != nil { |
| return err |
| } |
| if _, err = tabWriter.Write([]byte("\n")); err != nil { |
| return err |
| } |
| } |
| } else { |
| if err = tmpl.Execute(tabWriter, data); err != nil { |
| return err |
| } |
| if _, err = tabWriter.Write([]byte("\n")); err != nil { |
| return err |
| } |
| } |
| tabWriter.Flush() |
| return nil |
| } |
| |
| slice := reflect.ValueOf(data) |
| if slice.Kind() == reflect.Slice { |
| for i := 0; i < slice.Len(); i++ { |
| if err = tmpl.Execute(writer, slice.Index(i).Interface()); err != nil { |
| return err |
| } |
| if _, err = writer.Write([]byte("\n")); err != nil { |
| return err |
| } |
| } |
| } else { |
| if err = tmpl.Execute(writer, data); err != nil { |
| return err |
| } |
| if _, err = writer.Write([]byte("\n")); err != nil { |
| return err |
| } |
| } |
| return nil |
| |
| } |