pub struct NodeId { /* private fields */ }
Expand description
An identifier used to differentiate between Node
s within a Tree
.
NodeId
s are not something that the calling context will ever have to worry about generating.
Tree
s generate NodeId
s as Node
s are inserted into them.
In addition, each NodeId
is specific to the Tree
that generated it. This means that if
there are two Tree
s - 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 Tree
s pass out NodeId
s as Node
s are inserted, several issues can occur:
- If a
Node
is removed, theNodeId
that previously identified it now points to nothing (technically aNone
value in this case). - If a
Node
is removed and then another is inserted later, the “new”NodeId
that is returned can (and will) be the sameNodeId
that was used to identify a differentNode
previously.
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
Node
methods that provideNodeId
s will return&NodeId
s instead ofNodeId
s. - All
Tree
methods that read or insert data accept&NodeId
s instead of takingNodeId
s. - All
Tree
methods that remove data takeNodeId
s instead of accepting&NodeId
s. - All
Node
s that have been removed from aTree
will have their parent and child references cleared (to avoid leaking extraNodeId
copies). NodeId
s 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 Clone
s 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 NodeId
s refer to which
Node
s 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.