105 lines
2.7 KiB
Go
105 lines
2.7 KiB
Go
package format
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type DataFormat string
|
|
|
|
const (
|
|
List DataFormat = "list"
|
|
JSON DataFormat = "json"
|
|
YAML DataFormat = "yaml"
|
|
)
|
|
|
|
func (df DataFormat) String() string {
|
|
return string(df)
|
|
}
|
|
|
|
func (df *DataFormat) Set(v string) error {
|
|
switch DataFormat(v) {
|
|
case List, JSON, YAML:
|
|
*df = DataFormat(v)
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("must be one of %v", []DataFormat{
|
|
List, JSON, YAML,
|
|
})
|
|
}
|
|
}
|
|
|
|
func (df DataFormat) Type() string {
|
|
return "DataFormat"
|
|
}
|
|
|
|
// Marshal marshals arbitrary data into a byte slice formatted as outFormat.
|
|
// If a marshalling error occurs or outFormat is unknown, an error is returned.
|
|
//
|
|
// Supported values are: json, list, yaml
|
|
func Marshal(data any, outFormat DataFormat) ([]byte, error) {
|
|
switch outFormat {
|
|
case JSON:
|
|
if bytes, err := json.MarshalIndent(data, "", " "); err != nil {
|
|
return nil, fmt.Errorf("failed to marshal data into JSON: %w", err)
|
|
} else {
|
|
return bytes, nil
|
|
}
|
|
case YAML:
|
|
if bytes, err := yaml.Marshal(data); err != nil {
|
|
return nil, fmt.Errorf("failed to marshal data into YAML: %w", err)
|
|
} else {
|
|
return bytes, nil
|
|
}
|
|
case List:
|
|
return nil, fmt.Errorf("this data format cannot be marshaled")
|
|
default:
|
|
return nil, fmt.Errorf("unknown data format: %s", outFormat)
|
|
}
|
|
}
|
|
|
|
// Unmarshal unmarshals a byte slice formatted as inFormat into an interface
|
|
// v. If an unmarshalling error occurs or inFormat is unknown, an error is
|
|
// returned.
|
|
//
|
|
// Supported values are: json, list, yaml
|
|
func Unmarshal(data []byte, v any, inFormat DataFormat) error {
|
|
switch inFormat {
|
|
case JSON:
|
|
if err := json.Unmarshal(data, v); err != nil {
|
|
return fmt.Errorf("failed to unmarshal data into JSON: %w", err)
|
|
}
|
|
case YAML:
|
|
if err := yaml.Unmarshal(data, v); err != nil {
|
|
return fmt.Errorf("failed to unmarshal data into YAML: %w", err)
|
|
}
|
|
case List:
|
|
return fmt.Errorf("this data format cannot be unmarshaled")
|
|
default:
|
|
return fmt.Errorf("unknown data format: %s", inFormat)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DataFormatFromFileExt determines the type of the contents
|
|
// (JSON or YAML) based on the filname extension. The default
|
|
// format is passed in, so if it doesn't match one of the cases,
|
|
// that's what we will use. The defaultFmt value takes into account
|
|
// both the standard default format (JSON) and any command line
|
|
// change to that provided by options.
|
|
func DataFormatFromFileExt(path string, defaultFmt DataFormat) DataFormat {
|
|
switch strings.TrimLeft(strings.ToLower(filepath.Ext(path)), ".") {
|
|
case JSON.String():
|
|
// The file is a JSON file
|
|
return JSON
|
|
case YAML.String(), "yml":
|
|
// The file is a YAML file
|
|
return YAML
|
|
}
|
|
return defaultFmt
|
|
}
|