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)
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.
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.