class Eco::API::UseCases::GraphQL::Helpers::Location::Command::Diff module Compare # Sorts from top to bottom (parents go first) # @note # 1. The analysis below will assume that NO `nodeId` has changed. Which is what # this class helper tries to somehow ensure/emmulate. # 2. The below has been thought for NodesDiff::STAGES order: # [:unarchive, :id_name, :insert, :move, :archive] # @note # - If there was a change of id involved in child or parent, the method used # on each (attr vs prev_attr) could be different. We would need to know at # what stage we are in the general update. # - If MOVE has yet to come, `attr_prev` is alright, as we are interested # in the current parent-to-child order in the locations structure. # UNARCHIVE nodes have `attr_prev` and, therefore, this can be used to sort. # - If MOVE has happened, then `attr_prev` is missleading (order could be different), # so `attr` should be used, which refers to the final parents. However, # ARCHIVE nodes only have `attr_prev`, which could refer to the previous parent. And yet # as there's no current data, they have NOT been moved, which makes `prev_attr` reliable. # @note # - One thing is still to be resolved. `unarchive?` could entail a later `move?` (same NodeDiff). # Therefore, the STAGE when the comparison is done is relevant. # - This has been resolved with `sort_before_move` & `sort_after_move` methods. def <=>(other) if archive? || unarchive? return -1 if node_id_prev == other.parent_id_prev return 1 if parent_id_prev == other.node_id_prev elsif insert? || move? return -1 if node_id == other.parent_id return 1 if parent_id == other.node_id end 0 end def sort_before_move(other) self <=> other end def sort_after_move(other) if move? return -1 if node_id == other.parent_id return 1 if parent_id == other.node_id 0 else self <=> other end end end end