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

Add post-decode hook #253

Open
janslow opened this issue Sep 15, 2021 · 1 comment
Open

Add post-decode hook #253

janslow opened this issue Sep 15, 2021 · 1 comment

Comments

@janslow
Copy link

janslow commented Sep 15, 2021

Hi, thanks for the work you've done on this project.

One thing I've been struggling to do is run a function on the decoded value. I've got two use cases for this:

  1. Call an Initialize() function on any type that implements it, after decode has been completed (to apply custom configuration)
  2. Call a Validate() error function on any type that implements it, to perform custom validation.

Note, I want these to be performed on nested types (e.g., after type Foo struct { Bar Bar } is decoded, Bar.Validate() should be called if it exists), as well as allowing the parsing of Foo to be interrupted (i.e., if Foo.Bar.Validate() returns an error, the decoding of Foo should be be considered a failure, so mapstructure shouldn't try to decode any other fields.

Proposal

I could imagine mapstructure providing something like the following API to cover these use cases:

cfg := mapstructure.DecoderConfig{
	PostDecodeHook: mapstructure.ComposePostDecodeHookFunc(
		mapstructure.PostDecodeHookFunc(func(value reflect.Value) error {
			if v, ok := value.Interface().(Validatable); ok {
				return v.Validate()
			}
			return nil
		})
	),
	Result: &output,
}

This would be called at the end of the mapstructure.Decoder.decode() function, right before the final return statement.

Does this seem like a sensible enhancement? If so, I'm happy to put together a PR to implement it, if you'd consider reviewing it.

@davidcassany
Copy link

This is something I also have been wondering about. I am using mapstructure in conjunction with viper to load relatively complex yaml files into structs and having a hook to apply some logic right after the unmarshal is done would be really helpful to run some sanity checks and also prevent some co-occurrence issues. Obviously I can do the same as an extra step after unmarshaling, however having a chance to tie it all together at mapstructure level would be really nice.

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