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