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 }