VersionConstraint difference()

in lib/src/version_range.dart [286:396]


  VersionConstraint difference(VersionConstraint other) {
    if (other.isEmpty) return this;

    if (other is Version) {
      if (!allows(other)) return this;

      if (other == min) {
        if (!includeMin) return this;
        return VersionRange(
            min: min,
            max: max,
            includeMin: false,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true);
      }

      if (other == max) {
        if (!includeMax) return this;
        return VersionRange(
            min: min,
            max: max,
            includeMin: includeMin,
            includeMax: false,
            alwaysIncludeMaxPreRelease: true);
      }

      return VersionUnion.fromRanges([
        VersionRange(
            min: min,
            max: other,
            includeMin: includeMin,
            includeMax: false,
            alwaysIncludeMaxPreRelease: true),
        VersionRange(
            min: other,
            max: max,
            includeMin: false,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true)
      ]);
    } else if (other is VersionRange) {
      if (!allowsAny(other)) return this;

      VersionRange? before;
      if (!allowsLower(this, other)) {
        before = null;
      } else if (min == other.min) {
        assert(includeMin && !other.includeMin);
        assert(min != null);
        before = min;
      } else {
        before = VersionRange(
            min: min,
            max: other.min,
            includeMin: includeMin,
            includeMax: !other.includeMin,
            alwaysIncludeMaxPreRelease: true);
      }

      VersionRange? after;
      if (!allowsHigher(this, other)) {
        after = null;
      } else if (max == other.max) {
        assert(includeMax && !other.includeMax);
        assert(max != null);
        after = max;
      } else {
        after = VersionRange(
            min: other.max,
            max: max,
            includeMin: !other.includeMax,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true);
      }

      if (before == null && after == null) return VersionConstraint.empty;
      if (before == null) return after!;
      if (after == null) return before;
      return VersionUnion.fromRanges([before, after]);
    } else if (other is VersionUnion) {
      var ranges = <VersionRange>[];
      var current = this;

      for (var range in other.ranges) {
        // Skip any ranges that are strictly lower than [current].
        if (strictlyLower(range, current)) continue;

        // If we reach a range strictly higher than [current], no more ranges
        // will be relevant so we can bail early.
        if (strictlyHigher(range, current)) break;

        var difference = current.difference(range);
        if (difference.isEmpty) {
          return VersionConstraint.empty;
        } else if (difference is VersionUnion) {
          // If [range] split [current] in half, we only need to continue
          // checking future ranges against the latter half.
          assert(difference.ranges.length == 2);
          ranges.add(difference.ranges.first);
          current = difference.ranges.last;
        } else {
          current = difference as VersionRange;
        }
      }

      if (ranges.isEmpty) return current;
      return VersionUnion.fromRanges(ranges..add(current));
    }

    throw ArgumentError('Unknown VersionConstraint type $other.');
  }