Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for "custom" transformer/merges #49

Merged
merged 2 commits into from
Jan 11, 2018

Conversation

vdemeester
Copy link
Collaborator

I'm not sure the name transformer is not the right one.

But on docker/cli#569 we need to have a way to merge specific types differently that the default. This PR聽does that, on top of #45 馃懠

@the4thamigo-uk
Copy link

the4thamigo-uk commented Nov 13, 2017

I was thinking about doing something very similar to support issue #46. It would be nice to combine these ideas.

I have some general thoughts on this PR though, especially in relation to making it more generic :

  • I think it would be cleaner if, instead of having a transformer for each type, to simply specify a single transformer, as input to the public functions. Clients can then implement their own logic i.e. for Fail on conflict聽#46 I want to define a transformer that returns an error if the source and destination values are both not-nil and not-blank. With this PR, I would have to write a transformer func(dst reflect.Value, src reflect.Value) error for every type for which I want to apply that rule. Also I think, you could in principle, rewrite the existing overwrite behaviour with a transformer of this type.
  • Also I think it would be useful if instead of returning just error we returned (continue bool, err error). So that a transformer can decide whether to use the default merge code by specifying continue == true. This would be useful for issue Fail on conflict聽#46 and other kinds of transformation logic.
  • This PR modifies the existing public functions. It would be nice if we only added functions, to support existing users of the library.

@vdemeester
Copy link
Collaborator Author

@the4thamigo-uk thx :)

I think it would be cleaner if, instead of having a transformer for each type, to simply specify a single transformer, as input to the public functions. Clients can then implement their own logic i.e. for #46 I want to define a transformer that returns an error if the source and destination values are both not-nil and not-blank. With this PR, I would have to write a transformer func(dst reflect.Value, src reflect.Value) error for every type for which I want to apply that rule.

Actually you could have only a single transformer that has all the logic. Transformer(reflect.Type) func(dst, src reflect.Value) error doesn't force you to return different function for each type 馃懠. The way it's done now, you can either do one single transformer or compose then upstream (in the client code). But really, both would be fine to me.

Also I think it would be useful if instead of returning just error we returned (continue bool, err error). So that a transformer can decide whether to use the default merge code by specifying continue == true. This would be useful for issue #46 and other kinds of transformation logic.

I like that idea 馃懠

This PR modifies the existing public functions. It would be nice if we only added functions, to support existing users of the library.

Right, but it uses variadic arguments (can be 0 args then), and thus it support existing user of the library 馃懠. That's why there is no change in test files for example 馃槈. If we go for only one transformer, this is a different story and I do agree, I don't want to break current user of the library 馃懠

@the4thamigo-uk
Copy link

the4thamigo-uk commented Nov 13, 2017

Actually you could have only a single transformer that has all the logic. Transformer(reflect.Type) func(dst, src reflect.Value) error doesn't force you to return different function for each type 馃懠. The way it's done now, you can either do one single transformer or compose then upstream (in the client code). But really, both would be fine to me.

Well, ok it doesnt force you, but it implies that behaviour I think and it leads to a more constraints on the kind of rules you can write (and adds complexity). Also, you cant list a rule that is based on the types of both the source and destination types, unless everything is pushed into the transformer, so why not just have the transformer and forget about the list/slice. Personally I would go for simplicity...

Right, but it uses variadic arguments (can be 0 args then), and thus it support existing user of the library 馃懠. That's why there is no change in test files for example 馃槈. If we go for only one transformer, this is a different story and I do agree, I don't want to break current user of the library 馃懠

This is true but this isn't sufficient to make it compatible. i.e. an existing client code could have stored the merge function in a value, but since the function types are now different it is a breaking change.

@the4thamigo-uk
Copy link

Also #5 should be implementable with this change.

@darccio
Copy link
Owner

darccio commented Jan 4, 2018

I'll check your proposal this weekend. Thanks!

@darccio darccio merged commit 914266f into darccio:master Jan 11, 2018
darccio added a commit that referenced this pull request Jan 11, 2018
Add support for "custom" transformer/merges
@darccio
Copy link
Owner

darccio commented Jan 11, 2018

Although this is a backwards-compatibility breaking change, I think it adds flexibility to Mergo. I trust Docker's crew and the test looks solid, so it's in :)

@darccio
Copy link
Owner

darccio commented Jan 11, 2018

BTW, @vdemeester, please, could you add an example in README? Thanks!

@vdemeester vdemeester deleted the transformer-1 branch January 12, 2018 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants