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.
Trait Implementations§
Source§impl Ord for NodeId
impl Ord for NodeId
Source§impl PartialOrd for NodeId
impl PartialOrd for NodeId
impl Eq for NodeId
impl StructuralPartialEq for NodeId
Auto Trait Implementations§
impl Freeze for NodeId
impl RefUnwindSafe for NodeId
impl Send for NodeId
impl Sync for NodeId
impl Unpin for NodeId
impl UnwindSafe for NodeId
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more