Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Proposal: add generic Unmarshaler interface #304

Open
andig opened this issue Sep 2, 2022 · 1 comment
Open

Proposal: add generic Unmarshaler interface #304

andig opened this issue Sep 2, 2022 · 1 comment

Comments

@andig
Copy link

andig commented Sep 2, 2022

I've just had the requirement, to provide specific unmarshaling of some structures without modifying the unmarshaler configuration. I already have WeaklyTypedInput and DecodeHook/ComposeDecodeHookFunc.

I'd like to propose implementing an UnmarshallerHookFunc DecodeHookFunc. UnmarshallerHookFunc would be called whenever the target implements mapstructure.Unmarshaler:

type Unmarshaler interface {
	UnmarshalMapStructure(f reflect.Type, data interface{}) error
}

Here's an example usage case. ValueDefinition can be supplied as simple string or as map and both will be decoded into an ValueDefinition.

type ValueDefinition struct {
	Value string
	Scale float64
}

var _ util.MapStructureUnmarshaler = (*ValueDefinition)(nil)

func (v *ValueDefinition) UnmarshalMapStructure(f reflect.Type, data interface{}) error {
	switch f.Kind() {
	case reflect.String:
		*v = ValueDefinition{Value: data.(string)}
		return nil

	case reflect.Map:
		var cc struct {
			Value string
			Scale float64
		}

		err := util.DecodeOther(data, &cc)
		if err == nil {
			*v = ValueDefinition{
				Value: cc.Value,
				Scale: cc.Scale,
			}
		}

		return err

	default:
		return fmt.Errorf("invalid kind: %s", f.Kind())
	}
}

If that sounds interesting I'd be happy to provide a PR.

@Dragomir-Ivanov
Copy link

Hi @andig , you may find this project useful.
https://github.com/worldline-go/struct2

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants