diff --git a/conversions.go b/conversions.go index a849df1..2803083 100644 --- a/conversions.go +++ b/conversions.go @@ -14,7 +14,7 @@ import ( // separate the Base64 string from the security signature. const SignatureSeparator = "_" -// URLValuesSliceKeySuffix is the character that is used to +// urlValuesSliceKeySuffix is the character that is used to // specify a suffix for slices parsed by URLValues. // If the suffix is set to "[i]", then the index of the slice // is used in place of i @@ -29,6 +29,14 @@ const ( URLValuesSliceKeySuffixIndex = "[i]" ) +// URLValuesSliceKeySuffix returns the character that is used to +// specify a suffix for slices parsed by URLValues. +// +// The default suffix is "[]". +func URLValuesSliceKeySuffix() string { + return urlValuesSliceKeySuffix +} + // SetURLValuesSliceKeySuffix sets the character that is used to // specify a suffix for slices parsed by URLValues. // If the suffix is set to "[i]", then the index of the slice @@ -110,12 +118,25 @@ func cleanUpMapArray(in []Map) []Map { return result } +func cleanUpInterfaceMapArray(in []map[any]any) []Map { + if in == nil { + return nil + } + result := make([]Map, len(in)) + for i, v := range in { + result[i] = cleanUpInterfaceMap(v) + } + return result +} + func cleanUp(v any) any { switch v := v.(type) { case []any: return cleanUpInterfaceArray(v) case []map[string]any: return cleanUpMSIArray(v) + case []map[any]any: + return cleanUpInterfaceMapArray(v) case map[any]any: return cleanUpInterfaceMap(v) case map[string]any: diff --git a/conversions_nil_test.go b/conversions_nil_test.go index 415b4fd..df660f6 100644 --- a/conversions_nil_test.go +++ b/conversions_nil_test.go @@ -16,6 +16,7 @@ func TestConversionJSONPreservesNilContainers(t *testing.T) { {"nil interface slice", []any(nil), "null"}, {"nil map slice", []objx.Map(nil), "null"}, {"nil string map slice", []map[string]any(nil), "null"}, + {"nil interface map slice", []map[any]any(nil), "null"}, {"nil map", objx.Map(nil), "null"}, {"nil interface map", map[any]any(nil), "null"}, {"nil string map", map[string]any(nil), "null"}, @@ -24,11 +25,13 @@ func TestConversionJSONPreservesNilContainers(t *testing.T) { {"empty interface slice", []any{}, "[]"}, {"empty map slice", []objx.Map{}, "[]"}, {"empty string map slice", []map[string]any{}, "[]"}, + {"empty interface map slice", []map[any]any{}, "[]"}, {"empty map", objx.Map{}, "{}"}, {"empty interface map", map[any]any{}, "{}"}, {"populated interface slice", []any{1}, "[1]"}, {"populated map slice", []objx.Map{{"key": "value"}}, `[{"key":"value"}]`}, {"populated string map slice", []map[string]any{{"key": "value"}}, `[{"key":"value"}]`}, + {"populated interface map slice", []map[any]any{{"key": "value"}}, `[{"key":"value"}]`}, {"populated map", objx.Map{"key": "value"}, `{"key":"value"}`}, {"populated interface map", map[any]any{1: "value"}, `{"1":"value"}`}, } diff --git a/conversions_test.go b/conversions_test.go index 950e912..21fecab 100644 --- a/conversions_test.go +++ b/conversions_test.go @@ -23,10 +23,11 @@ func TestConversionJSON(t *testing.T) { "f": []objx.Map{{"g": map[any]any{"h": "i"}}}, "j": []map[string]any{{"k": map[any]any{"l": "m"}}}, "n": []any{objx.Map{"o": "p"}}, + "q": []map[any]any{{"r": map[any]any{"s": "t"}}}, }, } - jsonString = `{"a":{"b":{"c":{"d":"e"}},"f":[{"g":{"h":"i"}}],"j":[{"k":{"l":"m"}}],"n":[{"o":"p"}]}}` + jsonString = `{"a":{"b":{"c":{"d":"e"}},"f":[{"g":{"h":"i"}}],"j":[{"k":{"l":"m"}}],"n":[{"o":"p"}],"q":[{"r":{"s":"t"}}]}}` result, err = i.JSON() require.NoError(t, err) assert.Equal(t, jsonString, result) @@ -272,15 +273,25 @@ func TestConversionURLValuesNested(t *testing.T) { } func TestValidityURLQuerySliceKeySuffix(t *testing.T) { - t.Cleanup(func() { _ = objx.SetURLValuesSliceKeySuffix(objx.URLValuesSliceKeySuffixArray) }) + orig := objx.URLValuesSliceKeySuffix() + assert.Equal(t, objx.URLValuesSliceKeySuffixArray, orig) + t.Cleanup(func() { _ = objx.SetURLValuesSliceKeySuffix(orig) }) + err := objx.SetURLValuesSliceKeySuffix("") assert.Nil(t, err) + assert.Equal(t, objx.URLValuesSliceKeySuffixEmpty, objx.URLValuesSliceKeySuffix()) + err = objx.SetURLValuesSliceKeySuffix("[]") assert.Nil(t, err) + assert.Equal(t, objx.URLValuesSliceKeySuffixArray, objx.URLValuesSliceKeySuffix()) + err = objx.SetURLValuesSliceKeySuffix("[i]") assert.Nil(t, err) + assert.Equal(t, objx.URLValuesSliceKeySuffixIndex, objx.URLValuesSliceKeySuffix()) + err = objx.SetURLValuesSliceKeySuffix("{}") assert.Error(t, err) + assert.Equal(t, objx.URLValuesSliceKeySuffixIndex, objx.URLValuesSliceKeySuffix()) } func getURLQueryMap() objx.Map {