-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow sane conversions for As*Map*
and As*Array*
conversions
#11351
Conversation
Changelog[uncommitted] (2022-11-14)Features
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
1afe0af
to
4616eb7
Compare
Update generated code
4616eb7
to
5a419f1
Compare
bors r+ |
🕐 Waiting for PR status (GitHub check) to be set, probably by CI. Bors will automatically try to run when all required PR statuses are set. |
Build succeeded: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elegant solution!
// coerceTypeConversion assigns src to dst, performing deep type coercion as necessary. | ||
func coerceTypeConversion(src interface{}, dst reflect.Type) (interface{}, error) { | ||
makeError := func(src, dst reflect.Value) error { | ||
return fmt.Errorf("expected value of type %s, not %s", dst.Type(), src.Type()) | ||
} | ||
var coerce func(reflect.Value, reflect.Value) error | ||
coerce = func(src, dst reflect.Value) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good recursive algorithm 👍
Contravariance implemented in ApplyT is extremely general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a query, can any
not be used in place of interface{}
? Looks cleaner, but I'm guessing it is for backward compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're just using go's built in reflect.Type
fmt.Stringer
implementation. I was going for an error message that was similar to what we had before (i.(newType)
). I would assume that the go dev team prefers interface {}
over any
for backwards compatibility, but you'd need to ask them to be sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Graham-Beer we could use any
here if we updated go.mod to require 1.18 and above. I believe we'll be doing that soon anyhow as 1.17 is no longer supported.
Fixes #11348
Fixes #11347
This PR implements deep type conversion for the
As*Map
andAs*Array
methods onAnyOutput
.For example, you can now call
AsIntArrayMapOutput
on anAnyOutput
with underlying valuemap[string]interface{}{"zero": []int{0}, "one": []int{1}}
.I choose to implement this with reflection (as opposed to in the templating system) because I didn't want to handle the combinatorial explosion of outer and inner types. This solution works for arbitrary nesting of arbitrary types.