pub struct NodeId { /* private fields */ }Expand description
An identifier used to differentiate between Nodes within a Tree.
NodeIds are not something that the calling context will ever have to worry about generating.
Trees generate NodeIds as Nodes are inserted into them.
In addition, each NodeId is specific to the Tree that generated it. This means that if
there are two Trees - A and B - there’s no worry of trying to access a Node in A with
an identifier that came from B. Doing so will return a Result::Err value instead of
returning the wrong Node.
§Potential NodeId Issues
Because Trees pass out NodeIds as Nodes are inserted, several issues can occur:
- If a
Nodeis removed, theNodeIdthat previously identified it now points to nothing (technically aNonevalue in this case). - If a
Nodeis removed and then another is inserted later, the “new”NodeIdthat is returned can (and will) be the sameNodeIdthat was used to identify a differentNodepreviously.
The above issues may seem like deal-breakers, but our situation isn’t as bad as it seems:
The first issue can be easily detected by the library itself. In this situation, a
Result::Err will be returned with the appropriate NodeIdError. The second issue, however, is
not something that the library can detect. To mitigate this problem, this library ensures the
following:
- All
Nodemethods that provideNodeIds will return&NodeIds instead ofNodeIds. - All
Treemethods that read or insert data accept&NodeIds instead of takingNodeIds. - All
Treemethods that remove data takeNodeIds instead of accepting&NodeIds. - All
Nodes that have been removed from aTreewill have their parent and child references cleared (to avoid leaking extraNodeIdcopies). NodeIds themselves areClone, but notCopy.
This means that no methods will ever take ownership of a NodeId except for methods that remove
a Node from a Tree. The resulting behavior is that unless the caller explicitly Clones a
NodeId they should never be in a situation where they accidentally hold onto a NodeId too
long. This means that we have “almost safe references” that the caller can clone if they choose
to. Doing so, however, will open up the possibility of confusing which NodeIds refer to which
Nodes in the calling context.
This does transfer some of the burden to the caller, but any errors should be fairly easy to
sort out because an explicit Clone is required for such an error to occur.