get.porter.sh/porter@v1.3.0/pkg/encoding/encoding.go (about)

     1  package encoding
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"get.porter.sh/porter/pkg"
    11  	"github.com/carolynvs/aferox"
    12  	"github.com/pelletier/go-toml"
    13  	"gopkg.in/yaml.v3"
    14  )
    15  
    16  const (
    17  	Yaml = "yaml"
    18  	Json = "json"
    19  	Toml = "toml"
    20  )
    21  
    22  // MarshalFile encodes the specified struct to a file.
    23  // Supported file extensions are: yaml, yml, json, and toml.
    24  func MarshalFile(fs aferox.Aferox, path string, in interface{}) error {
    25  	format := strings.TrimPrefix(filepath.Ext(path), ".")
    26  	data, err := Marshal(format, in)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	return fs.WriteFile(path, data, pkg.FileModeWritable)
    31  }
    32  
    33  // MarshalYaml converts the input to yaml.
    34  func MarshalYaml(in interface{}) ([]byte, error) {
    35  	return Marshal(Yaml, in)
    36  }
    37  
    38  // MarshalJson converts the input struct to json.
    39  func MarshalJson(in interface{}) ([]byte, error) {
    40  	return Marshal(Json, in)
    41  }
    42  
    43  // MarshalToml converts the input to toml.
    44  func MarshalToml(in interface{}) ([]byte, error) {
    45  	return Marshal(Toml, in)
    46  }
    47  
    48  // Marshal a struct to the specified format.
    49  // Supported formats are: yaml, json, and toml.
    50  func Marshal(format string, in interface{}) (data []byte, err error) {
    51  	switch format {
    52  	case "json":
    53  		data, err = json.MarshalIndent(in, "", "  ")
    54  	case "yaml", "yml":
    55  		w := bytes.Buffer{}
    56  		encoder := yaml.NewEncoder(&w)
    57  		encoder.SetIndent(2)
    58  		err = encoder.Encode(in)
    59  		data = w.Bytes()
    60  	case "toml":
    61  		data, err = toml.Marshal(in)
    62  	default:
    63  		return nil, newUnsupportedFormatError(format)
    64  	}
    65  
    66  	if err != nil {
    67  		return nil, fmt.Errorf("error marshaling to %s: %w", format, err)
    68  	}
    69  
    70  	return data, nil
    71  }
    72  
    73  // Unmarshal from the specified file into a struct.
    74  // Supported file extensions are: yaml, yml, json, and toml.
    75  func UnmarshalFile(fs aferox.Aferox, path string, out interface{}) error {
    76  	data, err := fs.ReadFile(path)
    77  	if err != nil {
    78  		return fmt.Errorf("error reading file %s: %w", path, err)
    79  	}
    80  	format := strings.TrimPrefix(filepath.Ext(path), ".")
    81  	return Unmarshal(format, data, out)
    82  }
    83  
    84  // UnmarshalYaml converts the input yaml to a struct.
    85  func UnmarshalYaml(data []byte, out interface{}) error {
    86  	return Unmarshal(Yaml, data, out)
    87  }
    88  
    89  // UnmarshalJson converts the input json to a struct.
    90  func UnmarshalJson(data []byte, out interface{}) error {
    91  	return Unmarshal(Json, data, out)
    92  }
    93  
    94  // UnmarshalToml converts the input toml to a struct.
    95  func UnmarshalToml(data []byte, out interface{}) error {
    96  	return Unmarshal(Toml, data, out)
    97  }
    98  
    99  // Unmarshal from the specified format into a struct.
   100  // Supported formats are: yaml, json, and toml.
   101  func Unmarshal(format string, data []byte, out interface{}) error {
   102  	switch format {
   103  	case "json":
   104  		return json.Unmarshal(data, out)
   105  	case "yaml", "yml":
   106  		return yaml.Unmarshal(data, out)
   107  	case "toml":
   108  		return toml.Unmarshal(data, out)
   109  	default:
   110  		return newUnsupportedFormatError(format)
   111  	}
   112  }
   113  
   114  func newUnsupportedFormatError(format string) error {
   115  	return fmt.Errorf("unsupported format %s. Supported formats are: yaml, json and toml", format)
   116  }