-
Notifications
You must be signed in to change notification settings - Fork 2
Design questions #1
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
Comments
Ok so this is a bit complicated. The reason for all this weirdness has to do with fundamental incompatibilities between rust's type system and telegram's own json types. Due to the way rust handles generics rust types can't have circular references, i.e. contain themselves. Unfortunately, telegram types can have these cycles, so automatically generating rust types in a naive way breaks. To solve this, the easy way is to break cycles with a Box. This ends up being very expensive in terms of allocations if every field in every struct was all Box. The most runtime-efficient solution is to minimize the Boxen, boxing the fewest number of types in order to remove all cycles. This ends up being equivalent to minimum feedback arc set (https://en.wikipedia.org/wiki/Feedback_arc_set) which is NP hard so it must be approximated. The approximation doesn't have any guarantees of which particular fields are boxed, so exposing the fields as public would essentially be an unstable api. My solution to this was to only allow access via either Cows or Deref, since that can be created from a Box. I expose them both to allow ergonomics and better support for lifetimes (cows often have issues with complex lifetimes in trait bounds). If ownership is required a field can be cloned which is often inexpensive. If you or anyone has a better way of doing this I am definitely open to hearing it. |
I wrote my own types generator and I can say if you're not bothering with &'str and use owned types (mostly String) everywhere, there are only two places where you need |
Types that need to be boxed when owned include User and Message (as seen in Update type's children)There are cycles in the telegram API spec for types represented by json objects. |
I'm trying to migrate from another library to this one (because current one is unmaintained and doesn't support fresh features).
I have several questions regarding design choices:
Why are fields private?
Since types are generated they don't try to maintain invariants (like 'photo field should have caption' or something like this), so why bother and wrap everything into getter/setter methods?
Currently my code sometimes modify messages or entities and I have hard time porting this.
Why are Cows everywhere?
Ok, it may have some sense for requests (but it doesn't worth added complexity, imho), but why do it for response types, where all fields are read from network and thus are always owned (do I miss anything)?
The text was updated successfully, but these errors were encountered: