-
Notifications
You must be signed in to change notification settings - Fork 23
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 a transaction to own the underlying card #28
Comments
- Since Rust's support for self-referencial data structures is weak, there are cases where it is useful for a transaction to own the card and not just for it to hold a mutable reference. In these cases, the caller needs to explicitly end the transaction to recover the underlying card, but that is acceptable. - Generalize `Transaction` to be generic over a `BorrowMut<Card>`. Add new functions `Card::begin_transaction_owned` and `Card::begin_transaction2_owned` to create this type of transaction. Change `Transaction::end` to return the underlying card. And, add a variant, `Transaction::end2`, to unconditionally return the underlying card independent of whether ending the transaction succeeded. - Fixes bluetech#28.
Note: the provided patch changes the API. As such, it would be necessary to bump the version to 3.0. |
For more context, please see: https://gitlab.com/hkos/openpgp-card/-/issues/17 |
Hi @nwalfield, I've been thinking about this issue. Let me lay it out chronologically...
So my final thought is: your use case requires sufficient flexibility that the Rust borrow checker is just not worth dealing with. I think, let's keep What do you think? |
Hi @bluetech, Thanks for following up. I like option 4: having Option 6 (your final thought), I find worrying, because it is less type safe. Option 4 means that the API prevents the user from attempting to start a second transaction at compile time, because I don't think option 4 adds much complexity. If you agree, I'll implement it. Thanks in advance! |
I agree that the static safety provided by I think that option 6 is the best way forward, since it allows users when |
If the owner of the transaction calls drop (implicitly or explicitly) without getting the owned Card back, either it is a bug or intentional. If it is a bug, then the bug will be caught at compile time, because the compiler will complain that the Card has been moved when the developer tries to use the Card again. That's a clear benefit over option 6. It would make sense to provide option 6, if option 6 is more expressive. I'm having trouble envisioning a case where option 6 can be used to do something useful, which option 4 can't do. In other words, it seems to me that option 4 can do everything that option 6 can, but provides more safety. Do you have something in mind? |
Imagine that you have a small virtual machine, which is implemented as a state machine. It might be driven by a program like:
The state machine's state can't easily hold both the card and the transaction, because Rust doesn't like self-referential data structures. To work around this, the transaction could own the card.
The text was updated successfully, but these errors were encountered: