GregoireHENRY / rust-spice

WOW! The complete NASA/NAIF Spice toolkit is actually usable on Rust
Apache License 2.0
48 stars 16 forks source link

Builder pattern for writer functions #7

Open mclrc opened 2 years ago

mclrc commented 2 years ago

Hello! I'm creating this issue in response to your recommendation on implementing a builder-like pattern to call spkw09. This probably applies to most writer modules as a lot of them take a similar number of arguments.

There are a number of good typestate crates available for deriving a builder pattern for structs, however, I couldn't find any for functions. Of course, implementing a simple builder would be trivial using some struct that holds arguments in Options that can be unwrapped when the function call is dispatched. However, this would mean that leaving an option unset and then trying to dispatch the call would result in a runtime error when it really should be a compile time error - especially for use cases like mine, where the call to spkw09 happens after a lot of number crunching that can take a few minutes to complete.

One possible solution would be introducing a new struct like SPKSegment9 that we can derive a typestate builder pattern for (using something like typed-builder). The API could look something like this:

let mut segment = SPKSegment9::builder()
    .body(399)
    .states(&mut states)    
    // ...
    .build();
spice::spkw09(handle, &mut segment);

With this approach, calling build() before setting all fields results in a compile time error. You could also write the same segment to multiple kernels without much of a hassle. The only downside in my eyes is the introduction of a new struct that doesn't exist in CSPICE.

I don't want to rush this with a subpar custom builder implementation since the solution should ideally be robust enough to be used for other future writer module wrappers. What do you think? I can throw together a PR for the above idea if you like.

Cheers, have a nice day!