I am working on a tree algorithm. Inner nodes are used to navigate to the leaves, where the data resides. You can consider inner nodes to be index keys. The tree provides a query(index_key: String) method. While traversing down the tree, we compare the index_key provided with the index_keys stored in inner nodes. The query method should take a second argument, which is a closure implementing the logic for different operations, e.g.,
query(&self, index_key: String, op: impl FnMut() -> Vec<& Records>) -> Vec<& Records>
The method is implemented by Inner and Data nodes and should return modified (updated, deleted or found) records back. My dilemma is, whenever I use interior mutability, which looks like a logical option here, I am unable to return & Record references because the method calls borrow() to iterate through the children on a node, and the compiler complains:
cannot return value referencing temporary value
If I use references, since the op closure modifies the vectors in structs while iterating the tree, I need to use & mut references, which is a dead-end:
query(& mut self, index_key: String, op: impl FnMut() -> Vec<& mut Records>) -> Vec<& mut Records>
Because at some point I need another reference to the same struct, for example, to find out the number of children in a node etc., which is not allowed.
How does your design approach and mindset if you take on a Rust project? Meanwhile, I noticed that just focusing the algorithm doesn't help much.