diff --git a/defaults.go b/defaults.go index 97d7d6e6..e1eae4bf 100644 --- a/defaults.go +++ b/defaults.go @@ -3,6 +3,7 @@ package sprig import ( "bytes" "encoding/json" + "fmt" "reflect" "strings" ) @@ -63,6 +64,24 @@ func coalesce(v ...interface{}) interface{} { return nil } +// fromJSON decodes a JSON string to an item. +func fromJson(v interface{}) interface{} { + var result interface{} + switch v := v.(type) { + case []byte: + if err := json.Unmarshal(v, &result); err != nil { + panic(err) + } + case string: + if err := json.Unmarshal([]byte(v), &result); err != nil { + panic(err) + } + default: + panic(fmt.Errorf("Cannot decode JSON from type %T", v)) + } + return result +} + // toJson encodes an item into a JSON string func toJson(v interface{}) string { output, _ := json.Marshal(v) diff --git a/defaults_test.go b/defaults_test.go index 699ce2b8..65972284 100644 --- a/defaults_test.go +++ b/defaults_test.go @@ -83,6 +83,16 @@ func TestCoalesce(t *testing.T) { } } +func TestFromJson(t *testing.T) { + dict := map[string]interface{}{"Top": `{"number":42}`} + + tpl := `{{ index (.Top | fromJson) "number" }}` + expected := `42` + if err := runtv(tpl, expected, dict); err != nil { + t.Error(err) + } +} + func TestToJson(t *testing.T) { dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}} diff --git a/docs/defaults.md b/docs/defaults.md index 92b74830..050b732b 100644 --- a/docs/defaults.md +++ b/docs/defaults.md @@ -58,6 +58,16 @@ The above will first check to see if `.name` is empty. If it is not, it will ret that value. If it _is_ empty, `coalesce` will evaluate `.parent.name` for emptiness. Finally, if both `.name` and `.parent.name` are empty, it will return `Matt`. +## fromJson + +The `fromJson` function decodes data from a JSON string. If the item cannot be decoded the function will return an error. + +``` +fromJson .Value +``` + +The above decodes the JSON data from `.Value`. + ## toJson, mustToJson The `toJson` function encodes an item into a JSON string. If the item cannot be converted to JSON the function will return an empty string. diff --git a/functions.go b/functions.go index c16e9c3e..bb22a056 100644 --- a/functions.go +++ b/functions.go @@ -217,6 +217,7 @@ var genericMap = map[string]interface{}{ "empty": empty, "coalesce": coalesce, "compact": compact, + "fromJson": fromJson, "mustCompact": mustCompact, "toJson": toJson, "toPrettyJson": toPrettyJson,