-
Notifications
You must be signed in to change notification settings - Fork 378
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
Public interface for ToValue customization ? #426
Comments
Customising the conversion to and from a Value seems like a popular request (see #392 as well), but I haven't quite figured out how to do it properly yet. With the approach you mention I can see a few problems, main of which is you can't use 3rd party types. Also the interface is meant for a slightly different purpose, that is unwrapping Values, not converting to them. |
I did a quick proof-of-concept implementation in the linked pull-request. This would be enough for my need at least (even if I understand that this does not solve all related requests). |
Hi @dop251 , gentle ping to have your opinion on this since a mechanism like this would really help a lot in our codebase, thanks ! |
Hi. Sorry for the late answer. Following my latest changes I think it's possible to implement this: Add a method to set a custom "to value" converter to Runtime, i.e. func (r *Runtime) SetCustomToValue(converter func (interface{}) Value) { ... } If it is set, internally (i.e. when converting struct fields, map elements, etc.) this function will be called instead of the standard |
Thanks for the feedback, I'll try to have a look when I get the time |
@dop251 Is this idea of a custom converter for |
It is still valid, but it only covers one way (Go->JS), for exporting some other mechanism will be needed. |
Hi @dop251 I implemented a PoC of the mechanism discussed in this issue for both I made some changes in the interface of the custom converters to allow them to delegate the conversion to the default functions. In this way, the custom conversion can be selective. However, this approach has a limitation: it doesn't work for fields embedded in a struct, which is my original use case and pressing need. The reason is that the conversion logic for objects is not recursive (that is, it doesn't use the same function to convert each field in a struct) |
Hi @pablochacin. How about supporting recursive transformation as follows func NewCustomConverter(r *goja.Runtime) func (interface{}) goja.Value {
return func (i interface{}) goja.Value {
// You can use "r.ToValue()" if you want recursive conversion
}
} |
Hi @siyual-park That won't work because as I mentioned above, |
@pablochacin Oh, I misunderstood. So instead of passing the function, why don't you turn the interface over type Converter interface {
ToValue(i interface{}) (Value, bool)
// Maybe ExportTo could exist
} and use origin convert logic when custom converter return false |
No, that's not the problem @siyual-park . By recursive I mean being able to convert a field deep into a structure. Please take a look at the test in the PR I referenced before. Also, look at how the ToValue function works internally, you will see it delegates the conversion to a private function, which is not recursive either. |
Is it correct that the custom converter defined when converting a type such as structure or map is not called? @pablochacin When converting the deep type in the toValue function, it seems that it can be solved by recursively calling the toValue to convert the children, but it seems that the existing implementation may inevitably be modified quite a bit to connect with the existing go objects. Or if custom converter is defined, the implementation can be simplified by calling only the specified custom converter without fully calling the toValue used internally |
After more research, I found achieving custom conversion that includes fields in objects would require a significant rewrite of the goja runtime logic. Therefore, this approach seems only to work for a total replacement of the conversion logic, but is unsuitable to add custom conversion only for selected types. |
Is there any (hacky?) way to achieve this with today's goja API? |
Hi,
It would be really nice if the (r *Runtime) ToValue method could support an interface to allow custom conversion to goja values, working with reflect-based objects.
My use case would be to be able to declare custom generics types in go (like Option[T], Result[T,E]) and have them automatically handled anywhere in go values (either as field of structs or values in mappings for example).
There is already an internal interface with the right signature:
However there are two problems with this interface:
What do you think about this ?
The text was updated successfully, but these errors were encountered: