1package command
2
3import (
4	"bytes"
5	"fmt"
6	"io"
7	"text/template"
8
9	"github.com/ugorji/go/codec"
10)
11
12var (
13	jsonHandlePretty = &codec.JsonHandle{
14		HTMLCharsAsIs: true,
15		Indent:        4,
16	}
17)
18
19//DataFormatter is a transformer of the data.
20type DataFormatter interface {
21	// TransformData should return transformed string data.
22	TransformData(interface{}) (string, error)
23}
24
25// DataFormat returns the data formatter specified format.
26func DataFormat(format, tmpl string) (DataFormatter, error) {
27	switch format {
28	case "json":
29		if len(tmpl) > 0 {
30			return nil, fmt.Errorf("json format does not support template option.")
31		}
32		return &JSONFormat{}, nil
33	case "template":
34		return &TemplateFormat{tmpl}, nil
35	}
36	return nil, fmt.Errorf("Unsupported format is specified.")
37}
38
39type JSONFormat struct {
40}
41
42// TransformData returns JSON format string data.
43func (p *JSONFormat) TransformData(data interface{}) (string, error) {
44	var buf bytes.Buffer
45	enc := codec.NewEncoder(&buf, jsonHandlePretty)
46	err := enc.Encode(data)
47	if err != nil {
48		return "", err
49	}
50
51	return buf.String(), nil
52}
53
54type TemplateFormat struct {
55	tmpl string
56}
57
58// TransformData returns template format string data.
59func (p *TemplateFormat) TransformData(data interface{}) (string, error) {
60	var out io.Writer = new(bytes.Buffer)
61	if len(p.tmpl) == 0 {
62		return "", fmt.Errorf("template needs to be specified the golang templates.")
63	}
64
65	t, err := template.New("format").Parse(p.tmpl)
66	if err != nil {
67		return "", err
68	}
69
70	err = t.Execute(out, data)
71	if err != nil {
72		return "", err
73	}
74	return fmt.Sprint(out), nil
75}
76
77func Format(json bool, template string, data interface{}) (string, error) {
78	var format string
79	if json && len(template) > 0 {
80		return "", fmt.Errorf("Both json and template formatting are not allowed")
81	} else if json {
82		format = "json"
83	} else if len(template) > 0 {
84		format = "template"
85	} else {
86		return "", fmt.Errorf("no formatting option given")
87	}
88
89	f, err := DataFormat(format, template)
90	if err != nil {
91		return "", err
92	}
93
94	out, err := f.TransformData(data)
95	if err != nil {
96		return "", fmt.Errorf("Error formatting the data: %s", err)
97	}
98
99	return out, nil
100}
101