1
0
mirror of https://github.com/inexio/thola.git synced 2026-10-24 03:08:55 +03:00
Files
thola/internal/parser/object_parser.go
2021-09-07 12:23:52 +02:00

129 lines
2.9 KiB
Go

package parser
import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"github.com/gocarina/gocsv"
"github.com/inexio/thola/internal/tholaerr"
"github.com/inexio/thola/internal/utility"
"github.com/pkg/errors"
"reflect"
"strings"
)
type jsonParser interface {
ToJSON() ([]byte, error)
}
type xmlParser interface {
ToXML() ([]byte, error)
}
type csvParser interface {
ToCSV() ([]byte, error)
}
type humanReadableParser interface {
ToHumanReadable() ([]byte, error)
}
type toCheckPluginOutputParser interface {
ToCheckPluginOutput() ([]byte, error)
}
// Parse parses the object into the desired format
func Parse(i interface{}, format string) ([]byte, error) {
switch format {
case "json":
return ToJSON(i)
case "xml":
return ToXML(i)
case "csv":
return ToCSV(i)
case "check-plugin":
return ToCheckPluginOutput(i)
default:
return ToHumanReadable(i)
}
}
// ToXML parses the object to XML.
func ToXML(i interface{}) ([]byte, error) {
i = checkIfError(i)
if p, ok := i.(xmlParser); ok {
return p.ToXML()
}
response, err := xml.Marshal(i)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal to xml")
}
return response, nil
}
// ToJSON parses the object to JSON.
func ToJSON(i interface{}) ([]byte, error) {
i = checkIfError(i)
if p, ok := i.(jsonParser); ok {
return p.ToJSON()
}
response, err := json.Marshal(i)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal to json")
}
return response, nil
}
// ToCSV parses the object to CSV.
func ToCSV(i interface{}) ([]byte, error) {
i = checkIfError(i)
if p, ok := i.(csvParser); ok {
return p.ToCSV()
}
response, err := gocsv.MarshalBytes(i)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal to csv")
}
return response, nil
}
//ToHumanReadable parses the object to a human readable format.
func ToHumanReadable(i interface{}) ([]byte, error) {
i = checkIfError(i)
if p, ok := i.(humanReadableParser); ok {
return p.ToHumanReadable()
}
res := strings.TrimSpace(toHumanReadable(reflect.ValueOf(i), 0))
return []byte(utility.IfThenElseString(res == "", "No result", res)), nil
}
// ToCheckPluginOutput parses the object to a check plugin format.
func ToCheckPluginOutput(i interface{}) ([]byte, error) {
if p, ok := i.(toCheckPluginOutputParser); ok {
return p.ToCheckPluginOutput()
}
return nil, errors.New("object cannot be passed to check plugin output")
}
// ToStruct parses the formatted content into the struct with the correct unmarshal method.
func ToStruct(contents []byte, format string, i interface{}) error {
switch format {
case "json":
d := json.NewDecoder(bytes.NewReader(contents))
d.UseNumber()
return d.Decode(i)
case "xml":
return xml.Unmarshal(contents, i)
default:
return fmt.Errorf("invalid format '%s'", format)
}
}
func checkIfError(i interface{}) interface{} {
if err, ok := i.(error); ok {
i = tholaerr.OutputError{Error: err.Error()}
}
return i
}