mapstructure icon indicating copy to clipboard operation
mapstructure copied to clipboard

Fix DecodeHook support for decoding map from struct

Open pamburus opened this issue 6 years ago • 4 comments

pamburus avatar Aug 01 '19 12:08 pamburus

This issue is also causing me trouble. Effectively, it makes it so even though I can make string -> customType hook functions, hooks that go from customType -> string fail. The test included in the PR does a good job of showing this

camdencheek avatar Apr 02 '20 02:04 camdencheek

I would also greatly appreciate seeing this issue resolved. We are currently having to use a fork of mapstructure in our product.

djaglowski avatar Apr 03 '20 13:04 djaglowski

Hello! Apologies it has been awhile. I tried to fix the conflicts and merge this but the tests don't pass. If you can rebase and fix that, I'll merge just ping me.

mitchellh avatar Apr 20 '22 22:04 mitchellh

Ok, I've rebased the pull request and added temporary hack to make tests working. Also it seems that failing tests are connected with some existing contradictory logic.

TestDecode_StructTaggedWithOmitempty_OmitEmptyValues and TestDecode_StructTaggedWithOmitempty_KeepNonEmptyValues expect that typed nil pointer (VisibleNested) is decoded to a map[string]interface{} preserving the type of the pointer, i.e. as (*Nested)(nil).

But Decoder.decode has the following check that explicitly disables decoding of typed nil pointers:

	if input != nil {
		inputVal = reflect.ValueOf(input)

		// We need to check here if input is a typed nil. Typed nils won't
		// match the "input == nil" below so we check that here.
		if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
			input = nil
		}
	}

Why do we have 2 opposite decisions for decoding a simple value vs decoding a struct field? I guess decoding of a struct field of type A into a map with value of type B should reuse the same logic that is used to decode a scalar value of type A to a scalar value of type B.

So, let's decide whether we just fix the expectation of the tests to expect untyped nil values or we change the logic of decoding scalar values so that decoding of a typed nil to an interface{} will create an equivalent typed nil.

pamburus avatar Apr 24 '22 17:04 pamburus