Skip to content

Commit

Permalink
Added json input functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mikefarah committed Oct 11, 2015
1 parent 3720bf8 commit c955815
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 6 deletions.
34 changes: 34 additions & 0 deletions json_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ import (
"encoding/json"
)

func fromJSONBytes(jsonBytes []byte, parsedData *map[interface{}]interface{}) {
*parsedData = make(map[interface{}]interface{})
var jsonData map[string]interface{}
err := json.Unmarshal(jsonBytes, &jsonData)
if err != nil {
die("error parsing data: ", err)
}

for key, value := range jsonData {
(*parsedData)[key] = fromJSON(value)
}
}

func jsonToString(context interface{}) string {
out, err := json.Marshal(toJSON(context))
if err != nil {
Expand All @@ -12,6 +25,27 @@ func jsonToString(context interface{}) string {
return string(out)
}

func fromJSON(context interface{}) interface{} {
switch context.(type) {
case []interface{}:
oldArray := context.([]interface{})
newArray := make([]interface{}, len(oldArray))
for index, value := range oldArray {
newArray[index] = fromJSON(value)
}
return newArray
case map[string]interface{}:
oldMap := context.(map[string]interface{})
newMap := make(map[interface{}]interface{})
for key, value := range oldMap {
newMap[key] = fromJSON(value)
}
return newMap
default:
return context
}
}

func toJSON(context interface{}) interface{} {
switch context.(type) {
case []interface{}:
Expand Down
36 changes: 36 additions & 0 deletions json_converter_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
package main

import (
"encoding/json"
"fmt"
"os"
"testing"
)

func TestJsonFromString(t *testing.T) {
var data = parseJSONData(`
{
"b": {
"c": 2
}
}
`)
assertResult(t, "map[b:map[c:2]]", fmt.Sprintf("%v", data))
}

func TestJsonFromString_withArray(t *testing.T) {
var data = parseJSONData(`
{
"b": [
{ "c": 5 },
{ "c": 6 }
]
}
`)
assertResult(t, "map[b:[map[c:5] map[c:6]]]", fmt.Sprintf("%v", data))
}

func TestJsonToString(t *testing.T) {
var data = parseData(`
---
Expand All @@ -22,3 +48,13 @@ b:
`)
assertResult(t, "{\"b\":[{\"item\":\"one\"},{\"item\":\"two\"}]}", jsonToString(data))
}

func parseJSONData(rawData string) map[string]interface{} {
var parsedData map[string]interface{}
err := json.Unmarshal([]byte(rawData), &parsedData)
if err != nil {
fmt.Println("Error parsing json: ", err)
os.Exit(1)
}
return parsedData
}
1 change: 1 addition & 0 deletions sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"a":"Easy! as one two three","b":{"c":2,"d":[3,4],"e":[{"name":"fred","value":3},{"name":"sam","value":4}]}}
20 changes: 14 additions & 6 deletions yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
var trimOutput = true
var writeInplace = false
var writeScript = ""
var inputJSON = false
var outputToJSON = false

func main() {
Expand Down Expand Up @@ -61,6 +62,8 @@ a.b.e:
var rootCmd = &cobra.Command{Use: "yaml"}
rootCmd.PersistentFlags().BoolVarP(&trimOutput, "trim", "t", true, "trim yaml output")
rootCmd.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json")
rootCmd.PersistentFlags().BoolVarP(&inputJSON, "fromjson", "J", false, "input as json")

rootCmd.AddCommand(cmdRead, cmdWrite)
rootCmd.Execute()
}
Expand All @@ -72,7 +75,7 @@ func readProperty(cmd *cobra.Command, args []string) {
func read(args []string) interface{} {
var parsedData map[interface{}]interface{}

readYaml(args[0], &parsedData)
readData(args[0], &parsedData, inputJSON)

if len(args) == 1 {
return parsedData
Expand All @@ -95,7 +98,7 @@ func writeProperty(cmd *cobra.Command, args []string) {
func updateYaml(args []string) interface{} {
var writeCommands map[string]interface{}
if writeScript != "" {
readYaml(writeScript, &writeCommands)
readData(writeScript, &writeCommands, false)
} else if len(args) < 3 {
die("Must provide <filename> <path_to_update> <value>")
} else {
Expand All @@ -104,7 +107,7 @@ func updateYaml(args []string) interface{} {
}

var parsedData map[interface{}]interface{}
readYaml(args[0], &parsedData)
readData(args[0], &parsedData, inputJSON)

for path, value := range writeCommands {
var paths = parsePath(path)
Expand Down Expand Up @@ -154,7 +157,7 @@ func yamlToString(context interface{}) string {
return outStr
}

func readYaml(filename string, parsedData interface{}) {
func readData(filename string, parsedData interface{}, readAsJSON bool) {
if filename == "" {
die("Must provide filename")
}
Expand All @@ -166,9 +169,14 @@ func readYaml(filename string, parsedData interface{}) {
rawData = readFile(filename)
}

err := yaml.Unmarshal([]byte(rawData), parsedData)
var err interface{}
if readAsJSON {
fromJSONBytes([]byte(rawData), parsedData.(*map[interface{}]interface{}))
} else {
err = yaml.Unmarshal([]byte(rawData), parsedData)
}
if err != nil {
die("error: %v", err)
die("error parsing data: ", err)
}
}

Expand Down

0 comments on commit c955815

Please sign in to comment.