Tag method as callable only once

Hi,

I recently identified a potential misuse of a crate I've been developping.
The issue is quite simple, and I can easily document it, but I was wondering if it could actually be enforced in third-party code by the compiler.

I have a struct, which has a very limited number of methods:

  • new
  • activate_debug
  • solve
  • (and soon, fmt::debug)

This issue there is that the struct in question holds a lot of information needed for the algorithm that is running in some private fields, and the state of those fields is different between after and before calling the solve method, but could be useful for debugging purpose.
The actual limitation, is that the solve method should be called once and only once. If you want to solve another problem, you have to instanciate a new struct.
How can I tag this method so that the compiler knows about it. (In my case, the issue arise using criterion for benchmarking)

The struct in question:
https://docs.rs/newton_rootfinder/0.9.0/newton_rootfinder/solver/struct.RootFinder.html

Thanks in advance,
Best regards!

If you want the type system to prevent you from calling solve more than once, then you will have to take ownership of the model. For example, it could take self and return a solved model object.

1 Like

So basically, changing the signature from pub fn solve<M>(&mut self, model: &mut M) -> Result<(), crate::errors::SolverError<M, D>> to pub fn solve<M>(mut self, model: &mut M) -> Result<(), crate::errors::SolverError<M, D>>

For returning a solved model, I love the idea but I have to think about the design aspects of all the informations I want to return. My issue is that, especially when it failed, you might want to examine the struct final state (call fmt::debug after solve) and if the SolverError is returned, they will be no struct to inspect.

Yes, if you use this design, you need to return back the information that the user will want to inspect.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.