Section.merge constructor

Section.merge(
  1. Section value,
  2. Section other
)

Merges value and other into a new Section with combined labels and merged children.

Implementation

factory Section.merge(Section value, Section other) {
  final labels = <Label>[];
  final children = <Section>[];
  // Merging labels
  if (value.labels.isEmpty) {
    labels.addAll(other.labels);
  } else {
    for (var otherLabel in other.labels) {
      final existingLabel = value.labels.cast<Label?>().firstWhere(
            (x) => x!.key == otherLabel.key,
            orElse: () => null,
          );
      if (existingLabel == null) {
        labels.add(otherLabel);
      } else {
        labels.add(Label.merge(existingLabel, otherLabel));
      }
    }
    final labelsOnlyInValue = value.labels.where(
      (x) => !other.labels.any((o) => o.key == x.key),
    );
    labels.addAll(labelsOnlyInValue);
  }

  // Merging children
  if (value.children.isEmpty) {
    children.addAll(other.children);
  } else {
    for (var otherChild in other.children) {
      final existingChild = value.children.cast<Section?>().firstWhere(
            (x) => x!.key == otherChild.key,
            orElse: () => null,
          );
      if (existingChild == null) {
        children.add(otherChild);
      } else {
        children.add(Section.merge(existingChild, otherChild));
      }
    }
    final childrenOnlyInValue = value.children.where(
      (x) => !other.children.any((o) => o.key == x.key),
    );
    children.addAll(childrenOnlyInValue);
  }

  final result = Section(
    key: value.key,
    labels: labels,
    children: children,
  );

  Logger.root.finer(
      '[{SECTION} Merging]:\n\n\tITEM1===================================\n$value\n\n\tITEM2===================================\n$other\n\n\tRESULT===================================:\:\n$result\n\n');

  return result;
}