navigateTo method
Try to intelligently pop and push the stack to ensure destination
at the top. Or an stack with BadDestination will be returned.
It follows the following rules
- If current is
destination
, this is returned. - If
destination
can be pushed onto current, new nodes returned bydestination.tryNavigateFrom
will be pushed. - Pop and try again until suceeded or reach the root
- Try to push
destination
as root stack viadestination.tryBuildRootStack
. - BadDestination.unreachableLocation will be returned if all above failed.
Implementation
NavigationStack navigateTo(Destination destination,
{NavigationStack? origin}) {
// Destination reached, nothing to do.
if (current == destination) {
return this;
}
/// Try to push the destination onto the current stack.
final newNodes = destination.tryNavigateFrom(current);
if (newNodes != null) {
return pushAll(newNodes);
}
if (isRoot) {
// Can't pop any more, try to build as root.
final rootNodes = destination.tryBuildRootStack();
if (rootNodes != null) {
// Build root stack successfully.
return NavigationStack._fromNodes(rootNodes);
}
// Route is not reachable.
return BadDestination.unreachableLocation(
from: origin ?? this, to: destination)
.createStack();
}
// Pop then try again recursively.
return _stack!.navigateTo(destination, origin: origin ?? this);
}