From 822dc627a1cfdf1f97882f27761675ac6ace7669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 21 Dec 2018 16:21:13 +0100 Subject: tpl/transform: Add transform.Unmarshal func Fixes #5428 --- parser/metadecoders/format.go | 50 ++++++++++++++++++++++++++++++++++++++ parser/metadecoders/format_test.go | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) (limited to 'parser') diff --git a/parser/metadecoders/format.go b/parser/metadecoders/format.go index 3f5a8a5c1..4a30898fe 100644 --- a/parser/metadecoders/format.go +++ b/parser/metadecoders/format.go @@ -17,6 +17,8 @@ import ( "path/filepath" "strings" + "github.com/gohugoio/hugo/media" + "github.com/gohugoio/hugo/parser/pageparser" ) @@ -55,6 +57,18 @@ func FormatFromString(formatStr string) Format { } +// FormatFromMediaType gets the Format given a MIME type, empty string +// if unknown. +func FormatFromMediaType(m media.Type) Format { + for _, suffix := range m.Suffixes { + if f := FormatFromString(suffix); f != "" { + return f + } + } + + return "" +} + // FormatFromFrontMatterType will return empty if not supported. func FormatFromFrontMatterType(typ pageparser.ItemType) Format { switch typ { @@ -70,3 +84,39 @@ func FormatFromFrontMatterType(typ pageparser.ItemType) Format { return "" } } + +// FormatFromContentString tries to detect the format (JSON, YAML or TOML) +// in the given string. +// It return an empty string if no format could be detected. +func FormatFromContentString(data string) Format { + jsonIdx := strings.Index(data, "{") + yamlIdx := strings.Index(data, ":") + tomlIdx := strings.Index(data, "=") + + if isLowerIndexThan(jsonIdx, yamlIdx, tomlIdx) { + return JSON + } + + if isLowerIndexThan(yamlIdx, tomlIdx) { + return YAML + } + + if tomlIdx != -1 { + return TOML + } + + return "" +} + +func isLowerIndexThan(first int, others ...int) bool { + if first == -1 { + return false + } + for _, other := range others { + if other != -1 && other < first { + return false + } + } + + return true +} diff --git a/parser/metadecoders/format_test.go b/parser/metadecoders/format_test.go index a22e84f98..6243b3f1e 100644 --- a/parser/metadecoders/format_test.go +++ b/parser/metadecoders/format_test.go @@ -17,6 +17,8 @@ import ( "fmt" "testing" + "github.com/gohugoio/hugo/media" + "github.com/gohugoio/hugo/parser/pageparser" "github.com/stretchr/testify/require" @@ -41,6 +43,21 @@ func TestFormatFromString(t *testing.T) { } } +func TestFormatFromMediaType(t *testing.T) { + assert := require.New(t) + for i, test := range []struct { + m media.Type + expect Format + }{ + {media.JSONType, JSON}, + {media.YAMLType, YAML}, + {media.TOMLType, TOML}, + {media.CalendarType, ""}, + } { + assert.Equal(test.expect, FormatFromMediaType(test.m), fmt.Sprintf("t%d", i)) + } +} + func TestFormatFromFrontMatterType(t *testing.T) { assert := require.New(t) for i, test := range []struct { @@ -56,3 +73,28 @@ func TestFormatFromFrontMatterType(t *testing.T) { assert.Equal(test.expect, FormatFromFrontMatterType(test.typ), fmt.Sprintf("t%d", i)) } } + +func TestFormatFromContentString(t *testing.T) { + t.Parallel() + assert := require.New(t) + + for i, test := range []struct { + data string + expect interface{} + }{ + {`foo = "bar"`, TOML}, + {` foo = "bar"`, TOML}, + {`foo="bar"`, TOML}, + {`foo: "bar"`, YAML}, + {`foo:"bar"`, YAML}, + {`{ "foo": "bar"`, JSON}, + {`asdfasdf`, Format("")}, + {``, Format("")}, + } { + errMsg := fmt.Sprintf("[%d] %s", i, test.data) + + result := FormatFromContentString(test.data) + + assert.Equal(test.expect, result, errMsg) + } +} -- cgit v1.2.3