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

Mode types #13

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Conversation

Yoshanuikabundi
Copy link
Contributor

I refactored all the trajectory types to only implement the methods that were appropriate for the file mode it was opened in. This requires a lot of traits but means that mode checks happen at compile time rather than run time. Rust's type inference is really good, so all of the examples still work without modification :) Tests only needed changes to expected error types or construction of the private XdrFile struct, which doesn't have the open_read etc methods, which needed an explicit annotation. But neither of those things are things users would do, so this change should be a big plus for usability: No extra complications as long as you continue to use the open_read, open_append and open_write methods to construct trajectories, and statically checked file modes. Should even be faster and smaller in memory (by like a byte :P)

I also renamed XDRFile, XTCTrajectory and TRRTrajectory to XdrFile, XtcTrajectory and TrrTrajectory (which did require two changes to examples, just for clarity). This is in line with the Rust naming conventions:

In UpperCamelCase, acronyms count as one word: use Uuid rather than UUID.

This is an alternative to #11

@dnlbauer
Copy link
Owner

dnlbauer commented Nov 19, 2020

I'm ambivalent about this change. On one hand, having separate traits for Read/Write makes sense, but I think this implementation right now is a bit "over complex" for what it is trying to archive. This is mainly relating to the filemode.rs construct having a new module, several traits and structs together with additional ErrorFileModes in errors.rs. They have a simple intention in what they are trying to archive, but the amount of code is quite huge.

@Yoshanuikabundi
Copy link
Contributor Author

Yeah I was disappointed by how complex that got too. I'll have a think if there's anything I can do to simplify it.

@Yoshanuikabundi
Copy link
Contributor Author

Yoshanuikabundi commented Nov 20, 2020

OK I've gotten rid of two traits, ReaderMode and WriterMode. I think that's as good as it gets. Clone and PartialEq are both object-unsafe, so we can't just store a dyn FileMode and derive them on the Error enum. The options are, as I see them:

  1. Convert the mode to an enum and derive Clone and PartialEq (what I've implemented; 1 enum and 3 methods)
  2. Store a dyn Filemode in a struct and manually implement Clone and PartialEq on the struct (1 struct and 5 methods)
  3. Store the byte representation (b"r\0", b"w\0" or b"a\0") of the mode in the error enum (yuck)
  4. Store the debug representation of the mode in the error enum (yuck, but this is what we did for OutOfRange)
  5. Remove the mode from the Error::CouldNotOpen variant
  6. Manually implement Clone and PartialEq for Error (This is a terrible idea)
  7. Remove the Clone and PartialEq derives from Error (This is also a terrible idea)
  8. Do runtime mode checking via Mode checks #11

I think, of these, the enum (1) is the best option. The documentation is simple and clear, it's a tiny amount of code (25 lines of boilerplate and that's it) and everything happens in the type system so there's no need for any unreachable!()s or anything. The only alternatives I'd really consider would be 4 (which still requires the From impls, 17 of the 25 lines) or 7 (which has blocks of code throughout the codebase in doing runtime checks).

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

Successfully merging this pull request may close these issues.

2 participants