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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stringify on AnyPointer #397

Open
schreter opened this issue May 8, 2023 · 2 comments
Open

Stringify on AnyPointer #397

schreter opened this issue May 8, 2023 · 2 comments

Comments

@schreter
Copy link

schreter commented May 8, 2023

Now that dynamic reflection landed in capnp-rust (big thanks to David), we can easily Debug-print any capnp struct. However, these structs may contain AnyPointer, which currently doesn't print its own contents (for obvious reasons).

For example, in our project, we use AnyPointer in a generic outer request type to store the inner request. The inner request's structure ID is stored in the generic part and it's used for dispatching the inner request in the server. Now that we have reflection, we can print the contents of the outer and inner request for debugging purposes using our hand-crafted Debug implementation, based on the standard implementation in capnp.

However, I assume, our project is not the only one which uses AnyPointer. So the suggestion is to add a anyptr-debug-print hook to register a method to interpret the AnyPointer as a pointer to something else and/or to print it in the hook itself by dynamically evaluating the current structure containing the AnyPointer in question via the hook. Unfortunately, the formatter currently just gets the access to the pointer, but not to the outer structure, so the print function would require additional parameters for the optional parent dynamic structure and parent's field index which is being evaluated to be able to pass them to the hook to reinterpret the AnyPointer properly.

Opinions?

@dwrensha
Copy link
Member

dwrensha commented May 8, 2023

So the suggestion is to add a anyptr-debug-print hook to register a method to interpret the AnyPointer as a pointer to something else and/or to print it in the hook itself by dynamically evaluating the current structure containing the AnyPointer in question via the hook.

It sounds like you are suggesting using global mutable state? I think we should avoid that.

What if we instead exposed a public version of stringify::print() that had an additional parameter, allowing a custom printer registry to be passed in? I suppose one downside of this is that the custom printing would not work from Debug. Would that be a dealbreaker for you?

@schreter
Copy link
Author

schreter commented May 9, 2023

It sounds like you are suggesting using global mutable state? I think we should avoid that.

Yes, I'm aware that a global state is not a good design :-(. Unfortunately, I couldn't find anything better that would work with Debug directly.

Thinking it further, though, one option would be to somehow integrate it with annotations. I.e., if there is an annotation on AnyPointer with debug_print Rust function name, trigger this function somehow when printing the AnyPointer (of course, as noted above, together with the reference to the containing struct, so you can query the neighbouring fields to find out what it is and print it respectively).

There are some issues, though:

  • Not sure where this function pointer can be stored. Probably somewhere in compiled metadata in memory? I.e., in the code generated by the generator for the schema?
  • The Rust function name is "relative". I.e., if you use the same schema in two different crates, it might cause problems. However, in that case, one should anyway generate it only once and then use the external module, so it should be a non-issue.

What if we instead exposed a public version of stringify::print() that had an additional parameter, allowing a custom printer registry to be passed in?

This can be done on our side as well, so no need to do it directly in the capnp crate (unless many people want something like that :-)).

Would that be a dealbreaker for you?

It is definitely not a deal-breaker to NOT to have this at all, since we can add an own wrapper which does the necessary evaluation, it just needs to be used everywhere instead of the plain Debug output.

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

No branches or pull requests

2 participants