mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-08 19:36:36 +02:00
transform: Add support for "format" option in transform.Unmarshal
Fixes #13887
This commit is contained in:
@@ -36,6 +36,10 @@ import (
|
||||
|
||||
// Decoder provides some configuration options for the decoders.
|
||||
type Decoder struct {
|
||||
// Format specifies a specific format to decode from. If empty or
|
||||
// unspecified, it's inferred from the contents or the filename.
|
||||
Format string
|
||||
|
||||
// Delimiter is the field delimiter. Used in the CSV decoder. Default is
|
||||
// ','.
|
||||
Delimiter rune
|
||||
@@ -57,6 +61,7 @@ type Decoder struct {
|
||||
// OptionsKey is used in cache keys.
|
||||
func (d Decoder) OptionsKey() string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString(d.Format)
|
||||
sb.WriteRune(d.Delimiter)
|
||||
sb.WriteRune(d.Comment)
|
||||
sb.WriteString(strconv.FormatBool(d.LazyQuotes))
|
||||
|
@@ -72,9 +72,17 @@ func (ns *Namespace) Unmarshal(args ...any) (any, error) {
|
||||
}
|
||||
|
||||
v, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {
|
||||
f := metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)
|
||||
if f == "" {
|
||||
return nil, fmt.Errorf("MIME %q not supported", r.MediaType())
|
||||
var f metadecoders.Format
|
||||
if decoder.Format != "" {
|
||||
f = metadecoders.FormatFromString(decoder.Format)
|
||||
if f == "" {
|
||||
return nil, fmt.Errorf("format %q not supported", decoder.Format)
|
||||
}
|
||||
} else {
|
||||
f = metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)
|
||||
if f == "" {
|
||||
return nil, fmt.Errorf("MIME %q not supported", r.MediaType())
|
||||
}
|
||||
}
|
||||
|
||||
reader, err := r.ReadSeekCloser()
|
||||
@@ -119,10 +127,22 @@ func (ns *Namespace) Unmarshal(args ...any) (any, error) {
|
||||
|
||||
key := hashing.MD5FromStringHexEncoded(dataStr)
|
||||
|
||||
if decoder != metadecoders.Default {
|
||||
key += decoder.OptionsKey()
|
||||
}
|
||||
|
||||
v, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {
|
||||
f := decoder.FormatFromContentString(dataStr)
|
||||
if f == "" {
|
||||
return nil, errors.New("unknown format")
|
||||
var f metadecoders.Format
|
||||
if decoder.Format != "" {
|
||||
f = metadecoders.FormatFromString(decoder.Format)
|
||||
if f == "" {
|
||||
return nil, fmt.Errorf("format %q not supported", decoder.Format)
|
||||
}
|
||||
} else {
|
||||
f = decoder.FormatFromContentString(dataStr)
|
||||
if f == "" {
|
||||
return nil, errors.New("unknown format")
|
||||
}
|
||||
}
|
||||
|
||||
v, err := decoder.Unmarshal([]byte(dataStr), f)
|
||||
|
@@ -128,6 +128,9 @@ func TestUnmarshal(t *testing.T) {
|
||||
{testContentResource{key: "r1", content: `a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"delimiter": ";"}, func(r [][]string) {
|
||||
b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
|
||||
}},
|
||||
{testContentResource{key: "r1", content: `{p: [a, b]}`, mime: media.Builtin.JSONType}, map[string]any{"format": "yaml"}, func(m map[string]any) {
|
||||
b.Assert(m, qt.DeepEquals, map[string]any{"p": []any{"a", "b"}})
|
||||
}},
|
||||
{"a,b,c", nil, func(r [][]string) {
|
||||
b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
|
||||
}},
|
||||
@@ -141,6 +144,9 @@ a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"DElimiter": ";", "Comment"
|
||||
}},
|
||||
{``, nil, nil},
|
||||
{` `, nil, nil},
|
||||
{`{p: [a, b]}`, map[string]any{"format": "yaml"}, func(m map[string]any) {
|
||||
b.Assert(m, qt.DeepEquals, map[string]any{"p": []any{"a", "b"}})
|
||||
}},
|
||||
// errors
|
||||
{"thisisnotavaliddataformat", nil, false},
|
||||
{testContentResource{key: "r1", content: `invalid&toml"`, mime: media.Builtin.TOMLType}, nil, false},
|
||||
@@ -148,6 +154,8 @@ a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"DElimiter": ";", "Comment"
|
||||
{"thisisnotavaliddataformat", nil, false},
|
||||
{`{ notjson }`, nil, false},
|
||||
{tstNoStringer{}, nil, false},
|
||||
{"<root><a>notjson</a></root>", map[string]any{"format": "json"}, false},
|
||||
{"anything", map[string]any{"format": "invalidformat"}, false},
|
||||
} {
|
||||
|
||||
ns.Reset()
|
||||
|
Reference in New Issue
Block a user